Skip to content

Commit 103da93

Browse files
authored
[BUGFIX][Catalog] oracle catalog create table repeat and oracle pg null point (#5517)
1 parent 2c67cd8 commit 103da93

File tree

10 files changed

+321
-8
lines changed

10 files changed

+321
-8
lines changed

.github/workflows/backend.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -869,6 +869,31 @@ jobs:
869869
env:
870870
MAVEN_OPTS: -Xmx4096m
871871

872+
jdbc-connectors-it-part-6:
873+
needs: [ changes, sanity-check ]
874+
if: needs.changes.outputs.api == 'true'
875+
runs-on: ${{ matrix.os }}
876+
strategy:
877+
matrix:
878+
java: [ '8', '11' ]
879+
os: [ 'ubuntu-latest' ]
880+
timeout-minutes: 90
881+
steps:
882+
- uses: actions/checkout@v2
883+
- name: Set up JDK ${{ matrix.java }}
884+
uses: actions/setup-java@v3
885+
with:
886+
java-version: ${{ matrix.java }}
887+
distribution: 'temurin'
888+
cache: 'maven'
889+
- name: run jdbc connectors integration test (part-6)
890+
if: needs.changes.outputs.api == 'true'
891+
run: |
892+
./mvnw -B -T 1C verify -DskipUT=true -DskipIT=false -D"license.skipAddThirdParty"=true --no-snapshot-updates -pl :connector-jdbc-e2e-part-6 -am -Pci
893+
env:
894+
MAVEN_OPTS: -Xmx4096m
895+
896+
872897
kafka-connector-it:
873898
needs: [ changes, sanity-check ]
874899
if: needs.changes.outputs.api == 'true'

seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/AbstractJdbcCatalog.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -539,6 +539,7 @@ protected List<String> queryString(String url, String sql, ResultSetConsumer<Str
539539
// If sql is DDL, the execute() method always returns false, so the return value
540540
// should not be used to determine whether changes were made in database.
541541
protected boolean executeInternal(String url, String sql) throws SQLException {
542+
LOG.info("create table sql is: {}", sql);
542543
try (PreparedStatement ps = getConnection(url).prepareStatement(sql)) {
543544
return ps.execute();
544545
}

seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oracle/OracleCatalog.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,7 @@ protected String getCreateTableSql(TablePath tablePath, CatalogTable table) {
129129

130130
@Override
131131
protected String getDropTableSql(TablePath tablePath) {
132-
return String.format("DROP TABLE %s", getTableName(tablePath));
133-
}
134-
135-
@Override
136-
protected String getTableName(TablePath tablePath) {
137-
return tablePath.getSchemaAndTableName().toUpperCase();
132+
return String.format("DROP TABLE %s", tablePath.getSchemaAndTableName("\""));
138133
}
139134

140135
@Override

seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/oracle/OracleCreateTableSqlBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ private String buildColumnSql(Column column) {
9191
columnSql.append("\"").append(column.getName()).append("\" ");
9292

9393
String columnType =
94-
sourceCatalogName.equals("oracle")
94+
StringUtils.equalsIgnoreCase("oracle", sourceCatalogName)
9595
? column.getSourceType()
9696
: buildColumnType(column);
9797
columnSql.append(columnType);

seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/catalog/psql/PostgresCreateTableSqlBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ private String buildColumnSql(Column column) {
8989

9090
// For simplicity, assume the column type in SeaTunnelDataType is the same as in PostgreSQL
9191
String columnType =
92-
sourceCatalogName.equals("postgres")
92+
StringUtils.equalsIgnoreCase("postgres", sourceCatalogName)
9393
? column.getSourceType()
9494
: buildColumnType(column);
9595
columnSql.append(columnType);

seatunnel-connectors-v2/connector-jdbc/src/main/java/org/apache/seatunnel/connectors/seatunnel/jdbc/sink/JdbcSinkFactory.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ public TableSink createSink(TableSinkFactoryContext context) {
102102
catalogTable.getTableSchema(),
103103
catalogTable.getOptions(),
104104
catalogTable.getPartitionKeys(),
105+
catalogTable.getComment(),
105106
catalogTable.getCatalogName());
106107
}
107108
Map<String, String> map = config.toMap();
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Licensed to the Apache Software Foundation (ASF) under one or more
4+
contributor license agreements. See the NOTICE file distributed with
5+
this work for additional information regarding copyright ownership.
6+
The ASF licenses this file to You under the Apache License, Version 2.0
7+
(the "License"); you may not use this file except in compliance with
8+
the License. You may obtain a copy of the License at
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-->
16+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
17+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
18+
<modelVersion>4.0.0</modelVersion>
19+
<parent>
20+
<groupId>org.apache.seatunnel</groupId>
21+
<artifactId>connector-jdbc-e2e</artifactId>
22+
<version>${revision}</version>
23+
</parent>
24+
25+
<artifactId>connector-jdbc-e2e-part-6</artifactId>
26+
<name>SeaTunnel : E2E : Connector V2 : Jdbc : Part 2</name>
27+
28+
<dependencies>
29+
<dependency>
30+
<groupId>org.apache.seatunnel</groupId>
31+
<artifactId>connector-jdbc-e2e-common</artifactId>
32+
<version>${project.version}</version>
33+
<type>test-jar</type>
34+
<scope>test</scope>
35+
</dependency>
36+
37+
<dependency>
38+
<groupId>org.testcontainers</groupId>
39+
<artifactId>oracle-xe</artifactId>
40+
<version>${testcontainer.version}</version>
41+
<scope>test</scope>
42+
</dependency>
43+
44+
<!-- drivers -->
45+
<dependency>
46+
<groupId>com.oracle.database.jdbc</groupId>
47+
<artifactId>ojdbc8</artifactId>
48+
<scope>test</scope>
49+
</dependency>
50+
</dependencies>
51+
</project>
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
package org.apache.seatunnel.connectors.seatunnel.jdbc;
20+
21+
import org.apache.seatunnel.api.table.type.SeaTunnelRow;
22+
import org.apache.seatunnel.connectors.seatunnel.jdbc.catalog.oracle.OracleCatalog;
23+
import org.apache.seatunnel.connectors.seatunnel.jdbc.catalog.oracle.OracleURLParser;
24+
25+
import org.apache.commons.lang3.tuple.Pair;
26+
27+
import org.testcontainers.containers.GenericContainer;
28+
import org.testcontainers.containers.OracleContainer;
29+
import org.testcontainers.containers.output.Slf4jLogConsumer;
30+
import org.testcontainers.utility.DockerImageName;
31+
import org.testcontainers.utility.DockerLoggerFactory;
32+
import org.testcontainers.utility.MountableFile;
33+
34+
import com.google.common.collect.Lists;
35+
36+
import java.math.BigDecimal;
37+
import java.sql.Date;
38+
import java.sql.Timestamp;
39+
import java.time.LocalDate;
40+
import java.time.LocalDateTime;
41+
import java.util.ArrayList;
42+
import java.util.HashMap;
43+
import java.util.List;
44+
import java.util.Map;
45+
46+
public class JdbcOracleLowercaseTableIT extends AbstractJdbcIT {
47+
48+
private static final String ORACLE_IMAGE = "gvenzl/oracle-xe:21-slim-faststart";
49+
private static final String ORACLE_NETWORK_ALIASES = "e2e_oracleDb";
50+
private static final String DRIVER_CLASS = "oracle.jdbc.OracleDriver";
51+
private static final int ORACLE_PORT = 1521;
52+
private static final String ORACLE_URL = "jdbc:oracle:thin:@" + HOST + ":%s/%s";
53+
private static final String USERNAME = "TESTUSER";
54+
private static final String PASSWORD = "testPassword";
55+
private static final String DATABASE = "XE";
56+
private static final String SCHEMA = USERNAME;
57+
private static final String SOURCE_TABLE = "E2E_TABLE_SOURCE_LOWER";
58+
private static final String SINK_TABLE = "E2E_TABLE_SINK_LOWER";
59+
private static final String CATALOG_TABLE = "e2e_table_catalog_lower";
60+
// no execute conf just test lower oracle create table
61+
private static final List<String> CONFIG_FILE = Lists.newArrayList();
62+
63+
private static final String CREATE_SQL =
64+
"create table %s\n"
65+
+ "(\n"
66+
+ " VARCHAR_10_COL varchar2(10),\n"
67+
+ " CHAR_10_COL char(10),\n"
68+
+ " CLOB_COL clob,\n"
69+
+ " NUMBER_3_SF_2_DP number(3, 2),\n"
70+
+ " INTEGER_COL integer,\n"
71+
+ " FLOAT_COL float(10),\n"
72+
+ " REAL_COL real,\n"
73+
+ " BINARY_FLOAT_COL binary_float,\n"
74+
+ " BINARY_DOUBLE_COL binary_double,\n"
75+
+ " DATE_COL date,\n"
76+
+ " TIMESTAMP_WITH_3_FRAC_SEC_COL timestamp(3),\n"
77+
+ " TIMESTAMP_WITH_LOCAL_TZ timestamp with local time zone\n"
78+
+ ")";
79+
80+
@Override
81+
JdbcCase getJdbcCase() {
82+
Map<String, String> containerEnv = new HashMap<>();
83+
containerEnv.put("ORACLE_PASSWORD", PASSWORD);
84+
containerEnv.put("APP_USER", USERNAME);
85+
containerEnv.put("APP_USER_PASSWORD", PASSWORD);
86+
String jdbcUrl = String.format(ORACLE_URL, ORACLE_PORT, SCHEMA);
87+
Pair<String[], List<SeaTunnelRow>> testDataSet = initTestData();
88+
String[] fieldNames = testDataSet.getKey();
89+
90+
String insertSql = insertTable(SCHEMA, SOURCE_TABLE, fieldNames);
91+
92+
return JdbcCase.builder()
93+
.dockerImage(ORACLE_IMAGE)
94+
.networkAliases(ORACLE_NETWORK_ALIASES)
95+
.containerEnv(containerEnv)
96+
.driverClass(DRIVER_CLASS)
97+
.host(HOST)
98+
.port(ORACLE_PORT)
99+
.localPort(ORACLE_PORT)
100+
.jdbcTemplate(ORACLE_URL)
101+
.jdbcUrl(jdbcUrl)
102+
.userName(USERNAME)
103+
.password(PASSWORD)
104+
.database(DATABASE)
105+
.schema(SCHEMA)
106+
.sourceTable(SOURCE_TABLE)
107+
.sinkTable(SINK_TABLE)
108+
.catalogDatabase(DATABASE)
109+
.catalogSchema(SCHEMA)
110+
.catalogTable(CATALOG_TABLE)
111+
.createSql(CREATE_SQL)
112+
.configFile(CONFIG_FILE)
113+
.insertSql(insertSql)
114+
.testData(testDataSet)
115+
.build();
116+
}
117+
118+
@Override
119+
void compareResult() {}
120+
121+
@Override
122+
String driverUrl() {
123+
return "https://repo1.maven.org/maven2/com/oracle/database/jdbc/ojdbc8/12.2.0.1/ojdbc8-12.2.0.1.jar";
124+
}
125+
126+
@Override
127+
Pair<String[], List<SeaTunnelRow>> initTestData() {
128+
String[] fieldNames =
129+
new String[] {
130+
"VARCHAR_10_COL",
131+
"CHAR_10_COL",
132+
"CLOB_COL",
133+
"NUMBER_3_SF_2_DP",
134+
"INTEGER_COL",
135+
"FLOAT_COL",
136+
"REAL_COL",
137+
"BINARY_FLOAT_COL",
138+
"BINARY_DOUBLE_COL",
139+
"DATE_COL",
140+
"TIMESTAMP_WITH_3_FRAC_SEC_COL",
141+
"TIMESTAMP_WITH_LOCAL_TZ"
142+
};
143+
144+
List<SeaTunnelRow> rows = new ArrayList<>();
145+
for (int i = 0; i < 100; i++) {
146+
SeaTunnelRow row =
147+
new SeaTunnelRow(
148+
new Object[] {
149+
String.format("f%s", i),
150+
String.format("f%s", i),
151+
String.format("f%s", i),
152+
BigDecimal.valueOf(1.1),
153+
i,
154+
Float.parseFloat("2.2"),
155+
Float.parseFloat("2.2"),
156+
Float.parseFloat("22.2"),
157+
Double.parseDouble("2.2"),
158+
Date.valueOf(LocalDate.now()),
159+
Timestamp.valueOf(LocalDateTime.now()),
160+
Timestamp.valueOf(LocalDateTime.now())
161+
});
162+
rows.add(row);
163+
}
164+
165+
return Pair.of(fieldNames, rows);
166+
}
167+
168+
@Override
169+
GenericContainer<?> initContainer() {
170+
DockerImageName imageName = DockerImageName.parse(ORACLE_IMAGE);
171+
172+
GenericContainer<?> container =
173+
new OracleContainer(imageName)
174+
.withDatabaseName(SCHEMA)
175+
.withCopyFileToContainer(
176+
MountableFile.forClasspathResource("sql/oracle_init.sql"),
177+
"/container-entrypoint-startdb.d/init.sql")
178+
.withNetwork(NETWORK)
179+
.withNetworkAliases(ORACLE_NETWORK_ALIASES)
180+
.withExposedPorts(ORACLE_PORT)
181+
.withLogConsumer(
182+
new Slf4jLogConsumer(DockerLoggerFactory.getLogger(ORACLE_IMAGE)));
183+
184+
container.setPortBindings(
185+
Lists.newArrayList(String.format("%s:%s", ORACLE_PORT, ORACLE_PORT)));
186+
187+
return container;
188+
}
189+
190+
@Override
191+
public String quoteIdentifier(String field) {
192+
return "\"" + field + "\"";
193+
}
194+
195+
@Override
196+
protected void clearTable(String database, String schema, String table) {
197+
clearTable(schema, table);
198+
}
199+
200+
@Override
201+
protected String buildTableInfoWithSchema(String database, String schema, String table) {
202+
return buildTableInfoWithSchema(schema, table);
203+
}
204+
205+
@Override
206+
protected void initCatalog() {
207+
String jdbcUrl = jdbcCase.getJdbcUrl().replace(HOST, dbServer.getHost());
208+
catalog =
209+
new OracleCatalog(
210+
"oracle",
211+
jdbcCase.getUserName(),
212+
jdbcCase.getPassword(),
213+
OracleURLParser.parse(jdbcUrl),
214+
SCHEMA);
215+
catalog.open();
216+
}
217+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--
2+
-- Licensed to the Apache Software Foundation (ASF) under one or more
3+
-- contributor license agreements. See the NOTICE file distributed with
4+
-- this work for additional information regarding copyright ownership.
5+
-- The ASF licenses this file to You under the Apache License, Version 2.0
6+
-- (the "License"); you may not use this file except in compliance with
7+
-- the License. You may obtain a copy of the License at
8+
--
9+
-- http://www.apache.org/licenses/LICENSE-2.0
10+
--
11+
-- Unless required by applicable law or agreed to in writing, software
12+
-- distributed under the License is distributed on an "AS IS" BASIS,
13+
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
-- See the License for the specific language governing permissions and
15+
-- limitations under the License.
16+
--
17+
18+
ALTER SESSION SET CONTAINER = TESTUSER;
19+
20+
CREATE USER TESTUSER IDENTIFIED BY testPassword;
21+
22+
GRANT DBA TO TESTUSER;

seatunnel-e2e/seatunnel-connector-v2-e2e/connector-jdbc-e2e/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
<module>connector-jdbc-e2e-part-3</module>
3434
<module>connector-jdbc-e2e-part-4</module>
3535
<module>connector-jdbc-e2e-part-5</module>
36+
<module>connector-jdbc-e2e-part-6</module>
3637
</modules>
3738

3839
<dependencyManagement>

0 commit comments

Comments
 (0)