Skip to content

Commit 634100d

Browse files
committed
Fix DB2 storage of binary data in char column (#1307)
See #1304 Signed-off-by: Thomas Segismont <tsegismont@gmail.com>
1 parent 1d283bb commit 634100d

File tree

4 files changed

+110
-67
lines changed

4 files changed

+110
-67
lines changed

vertx-db2-client/src/main/java/io/vertx/db2client/impl/codec/DB2ParamDesc.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ private static boolean canConvert(Object val, int type) {
6767
return clazz == Numeric.class;
6868
case ClientTypes.VARCHAR:
6969
return Enum.class.isAssignableFrom(clazz) || Buffer.class.isAssignableFrom(clazz);
70+
case ClientTypes.BINARY:
7071
case ClientTypes.VARBINARY:
7172
return Buffer.class.isAssignableFrom(clazz);
7273
}

vertx-db2-client/src/test/java/io/vertx/db2client/DB2DataTypeTest.java

Lines changed: 81 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,35 @@
1515
*/
1616
package io.vertx.db2client;
1717

18-
import static org.junit.Assume.assumeTrue;
18+
import io.vertx.core.buffer.Buffer;
19+
import io.vertx.ext.unit.TestContext;
20+
import io.vertx.ext.unit.junit.VertxUnitRunner;
21+
import io.vertx.sqlclient.Row;
22+
import io.vertx.sqlclient.RowSet;
23+
import io.vertx.sqlclient.Tuple;
24+
import org.junit.Test;
25+
import org.junit.runner.RunWith;
1926

2027
import java.sql.RowId;
2128
import java.time.LocalDateTime;
2229
import java.time.temporal.ChronoField;
2330
import java.util.Arrays;
31+
import java.util.Collections;
32+
import java.util.List;
2433
import java.util.UUID;
2534

26-
import org.junit.Test;
27-
import org.junit.runner.RunWith;
28-
29-
import io.vertx.core.buffer.Buffer;
30-
import io.vertx.ext.unit.TestContext;
31-
import io.vertx.ext.unit.junit.VertxUnitRunner;
32-
import io.vertx.sqlclient.Row;
33-
import io.vertx.sqlclient.RowSet;
34-
import io.vertx.sqlclient.Tuple;
35+
import static org.junit.Assume.assumeTrue;
3536

3637
@RunWith(VertxUnitRunner.class)
3738
public class DB2DataTypeTest extends DB2TestBase {
3839

3940

40-
// Enum for enum testing
41+
// Enum for enum testing
4142
enum Days {
4243
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
4344
}
4445

45-
46+
4647
/**
4748
* In DB2 the FLOAT and DOUBLE column types both map to an 8-byte
4849
* double-precision column (i.e. Java double). Ensure that a Java
@@ -85,41 +86,75 @@ public void testByteIntoSmallIntColumn(TestContext ctx) {
8586
}));
8687
}
8788

89+
@Test
90+
public void testByteArrayIntoChar(TestContext ctx) {
91+
byte[] param = "hello world".getBytes();
92+
byte[] expected = new byte[255];
93+
Arrays.fill(expected, (byte) 32);
94+
System.arraycopy(param, 0, expected, 0, param.length);
95+
testByteArrayInto(ctx, "test_bytes", param, expected);
96+
}
97+
8898
@Test
8999
public void testByteArrayIntoVarchar(TestContext ctx) {
90-
byte[] expected = "hello world".getBytes();
100+
byte[] param = "hello world".getBytes();
101+
testByteArrayInto(ctx, "test_vbytes", param, param);
102+
}
103+
104+
private void testByteArrayInto(TestContext ctx, String colName, byte[] param, byte[] expected) {
91105
connect(ctx.asyncAssertSuccess(conn -> {
92-
conn.preparedQuery("INSERT INTO db2_types (id,test_bytes) VALUES (?, ?)")
93-
.execute(Tuple.of(3, "hello world".getBytes()), ctx.asyncAssertSuccess(insertResult -> {
94-
conn.preparedQuery("SELECT id,test_bytes FROM db2_types WHERE id = 3")
95-
.execute(ctx.asyncAssertSuccess(rows -> {
96-
ctx.assertEquals(1, rows.size());
97-
Row row = rows.iterator().next();
98-
ctx.assertEquals(3, row.getInteger(0));
99-
ctx.assertTrue(Arrays.equals(expected, row.getBuffer(1).getBytes()),
100-
"Expecting " + Arrays.toString(expected) + " but got "
101-
+ Arrays.toString(row.getBuffer(1).getBytes()));
102-
}));
103-
}));
106+
conn
107+
.preparedQuery("INSERT INTO db2_types (id," + colName + ") VALUES (?, ?)")
108+
.execute(Tuple.of(3, param))
109+
.onComplete(ctx.asyncAssertSuccess(insertResult -> {
110+
conn
111+
.preparedQuery("SELECT id," + colName + " FROM db2_types WHERE id = 3")
112+
.execute()
113+
.onComplete(ctx.asyncAssertSuccess(rows -> {
114+
ctx.assertEquals(1, rows.size());
115+
Row row = rows.iterator().next();
116+
ctx.assertEquals(3, row.getInteger(0));
117+
ctx.assertTrue(Arrays.equals(expected, row.getBuffer(1).getBytes()),
118+
"Expecting " + Arrays.toString(expected) + " but got "
119+
+ Arrays.toString(row.getBuffer(1).getBytes()));
120+
}));
121+
}));
104122
}));
105123
}
106124

107125
@Test
108-
public void testByteBufIntoVarchar(TestContext ctx) {
109-
byte[] expected = "hello world".getBytes();
126+
public void testBufferIntoChar(TestContext ctx) {
127+
byte[] param = "hello world".getBytes();
128+
byte[] expected = new byte[255];
129+
Arrays.fill(expected, (byte) 32);
130+
System.arraycopy(param, 0, expected, 0, param.length);
131+
testBufferInto(ctx, "test_bytes", param, expected);
132+
}
133+
134+
@Test
135+
public void testBufferIntoVarchar(TestContext ctx) {
136+
byte[] param = "hello world".getBytes();
137+
testBufferInto(ctx, "test_vbytes", param, param);
138+
}
139+
140+
private void testBufferInto(TestContext ctx, String colName, byte[] param, byte[] expected) {
110141
connect(ctx.asyncAssertSuccess(conn -> {
111-
conn.preparedQuery("INSERT INTO db2_types (id,test_bytes) VALUES (?, ?)")
112-
.execute(Tuple.of(4, Buffer.buffer(expected)), ctx.asyncAssertSuccess(insertResult -> {
113-
conn.preparedQuery("SELECT id,test_bytes FROM db2_types WHERE id = 4")
114-
.execute(ctx.asyncAssertSuccess(rows -> {
115-
ctx.assertEquals(1, rows.size());
116-
Row row = rows.iterator().next();
117-
ctx.assertEquals(4, row.getInteger(0));
118-
ctx.assertTrue(Arrays.equals(expected, row.getBuffer(1).getBytes()),
119-
"Expecting " + Arrays.toString(expected) + " but got "
120-
+ Arrays.toString(row.getBuffer(1).getBytes()));
121-
}));
122-
}));
142+
conn
143+
.preparedQuery("INSERT INTO db2_types (id," + colName + ") VALUES (?, ?)")
144+
.execute(Tuple.of(4, Buffer.buffer(param)))
145+
.onComplete(ctx.asyncAssertSuccess(insertResult -> {
146+
conn
147+
.preparedQuery("SELECT id," + colName + " FROM db2_types WHERE id = 4")
148+
.execute()
149+
.onComplete(ctx.asyncAssertSuccess(rows -> {
150+
ctx.assertEquals(1, rows.size());
151+
Row row = rows.iterator().next();
152+
ctx.assertEquals(4, row.getInteger(0));
153+
ctx.assertTrue(Arrays.equals(expected, row.getBuffer(1).getBytes()),
154+
"Expecting " + Arrays.toString(expected) + " but got "
155+
+ Arrays.toString(row.getBuffer(1).getBytes()));
156+
}));
157+
}));
123158
}));
124159
}
125160

@@ -183,7 +218,7 @@ public void testRowId(TestContext ctx) {
183218
}));
184219
}));
185220
}
186-
221+
187222
/**
188223
* Test to support using enum string values in the Row and Tuple methods.
189224
*/
@@ -221,7 +256,7 @@ public void testUsingEnumOrdinalValue(TestContext ctx) {
221256
}));
222257
}));
223258
}
224-
259+
225260
private RowId verifyRowId(TestContext ctx, RowSet<Row> rows, String msg) {
226261
ctx.assertEquals(1, rows.size());
227262
Row row = rows.iterator().next();
@@ -231,4 +266,9 @@ private RowId verifyRowId(TestContext ctx, RowSet<Row> rows, String msg) {
231266
ctx.assertEquals(22, rowid.getBytes().length);
232267
return rowid;
233268
}
269+
270+
@Override
271+
protected List<String> tablesToClean() {
272+
return Collections.singletonList("db2_types");
273+
}
234274
}

vertx-db2-client/src/test/resources/init.sql

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,21 +70,21 @@ CREATE TABLE basicdatatype
7070
test_date DATE,
7171
test_time TIME
7272
);
73-
INSERT INTO basicdatatype(id, test_int_2, test_int_4, test_int_8,
74-
test_float_4, test_float_8, test_numeric, test_decimal,
75-
test_boolean, test_char, test_varchar,
73+
INSERT INTO basicdatatype(id, test_int_2, test_int_4, test_int_8,
74+
test_float_4, test_float_8, test_numeric, test_decimal,
75+
test_boolean, test_char, test_varchar,
7676
test_date, test_time)
77-
VALUES (1, 32767, 2147483647, 9223372036854775807,
78-
3.40282E38, 1.7976931348623157E308, 999.99, 12345,
79-
TRUE, 'testchar', 'testvarchar',
77+
VALUES (1, 32767, 2147483647, 9223372036854775807,
78+
3.40282E38, 1.7976931348623157E308, 999.99, 12345,
79+
TRUE, 'testchar', 'testvarchar',
8080
'2019-01-01', '18:45:02');
81-
INSERT INTO basicdatatype(id, test_int_2, test_int_4, test_int_8,
82-
test_float_4, test_float_8, test_numeric, test_decimal,
83-
test_boolean, test_char, test_varchar,
81+
INSERT INTO basicdatatype(id, test_int_2, test_int_4, test_int_8,
82+
test_float_4, test_float_8, test_numeric, test_decimal,
83+
test_boolean, test_char, test_varchar,
8484
test_date, test_time)
85-
VALUES (2, 32767, 2147483647, 9223372036854775807,
86-
3.40282E38, 1.7976931348623157E308, 999.99, 12345,
87-
TRUE, 'testchar', 'testvarchar',
85+
VALUES (2, 32767, 2147483647, 9223372036854775807,
86+
3.40282E38, 1.7976931348623157E308, 999.99, 12345,
87+
TRUE, 'testchar', 'testvarchar',
8888
'2019-01-01', '18:45:02');
8989
INSERT INTO basicdatatype(id, test_int_2, test_int_4, test_int_8, test_float_4, test_float_8, test_numeric, test_decimal, test_boolean, test_char, test_varchar, test_date, test_time)
9090
VALUES (3, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
@@ -109,13 +109,14 @@ INSERT INTO collector_test VALUES (2, 32767, 2147483647, 9223372036854775807, 12
109109
DROP TABLE IF EXISTS db2_types;
110110
CREATE TABLE db2_types
111111
(
112-
id INT,
113-
test_byte SMALLINT,
114-
test_float FLOAT,
115-
test_bytes VARCHAR(255) for bit data,
116-
test_tstamp TIMESTAMP,
117-
test_vchar VARCHAR(255),
118-
test_int INT
112+
id INT,
113+
test_byte SMALLINT,
114+
test_float FLOAT,
115+
test_bytes CHAR(255) for bit data,
116+
test_vbytes VARCHAR(255) for bit data,
117+
test_tstamp TIMESTAMP,
118+
test_vchar VARCHAR(255),
119+
test_int INT
119120
);
120121

121122
-- Sequence used by QueryVariationsTest

vertx-db2-client/src/test/resources/init.zos.sql

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,14 @@ CREATE TABLE ROWTEST(
119119
DROP TABLE db2_types;
120120
CREATE TABLE db2_types
121121
(
122-
id INT,
123-
test_byte SMALLINT,
124-
test_float FLOAT,
125-
test_bytes VARCHAR(255) for bit data,
126-
test_tstamp TIMESTAMP,
127-
test_vchar VARCHAR(255),
128-
test_int INT
122+
id INT,
123+
test_byte SMALLINT,
124+
test_float FLOAT,
125+
test_bytes CHAR(255) for bit data,
126+
test_vbytes VARCHAR(255) for bit data,
127+
test_tstamp TIMESTAMP,
128+
test_vchar VARCHAR(255),
129+
test_int INT
129130
);
130131

131132
-- Sequence used by QueryVariationsTest

0 commit comments

Comments
 (0)