Skip to content

Commit e82128e

Browse files
committed
fix
1 parent f8c11bf commit e82128e

3 files changed

Lines changed: 98 additions & 17 deletions

File tree

database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacket.java

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package org.apache.shardingsphere.database.protocol.postgresql.packet.command.query;
1919

2020
import lombok.Getter;
21-
import lombok.RequiredArgsConstructor;
2221
import org.apache.shardingsphere.database.protocol.binary.BinaryCell;
2322
import org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValue;
2423
import org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.bind.protocol.PostgreSQLBinaryProtocolValueFactory;
@@ -50,7 +49,6 @@
5049
/**
5150
* Data row packet for PostgreSQL.
5251
*/
53-
@RequiredArgsConstructor
5452
@Getter
5553
public final class PostgreSQLDataRowPacket extends PostgreSQLIdentifierPacket {
5654

@@ -80,7 +78,13 @@ public final class PostgreSQLDataRowPacket extends PostgreSQLIdentifierPacket {
8078

8179
private final Collection<Integer> columnTypes;
8280

83-
private final String sessionTimeZone;
81+
private final ZoneId sessionTimeZone;
82+
83+
public PostgreSQLDataRowPacket(final Collection<Object> data, final Collection<Integer> columnTypes, final String sessionTimeZone) {
84+
this.data = data;
85+
this.columnTypes = columnTypes;
86+
this.sessionTimeZone = getSessionZone(sessionTimeZone);
87+
}
8488

8589
@Override
8690
protected void write(final PostgreSQLPacketPayload payload) {
@@ -129,9 +133,9 @@ private void writeTextValue(final PostgreSQLPacketPayload payload, final Object
129133
} else if (Types.TIME_WITH_TIMEZONE == columnType) {
130134
String formatted = "";
131135
if (each instanceof LocalTime) {
132-
formatted = TIME_FORMATTER.format(((LocalTime) each).atDate(LocalDate.now()).atZone(getSessionZone(sessionTimeZone)));
136+
formatted = TIME_FORMATTER.format(((LocalTime) each).atDate(LocalDate.now()).atZone(sessionTimeZone));
133137
} else if (each instanceof OffsetTime) {
134-
formatted = TIME_FORMATTER.format((OffsetTime) each);
138+
formatted = TIME_FORMATTER.format(((OffsetTime) each).atDate(LocalDate.now()).toInstant().atZone(sessionTimeZone));
135139
} else {
136140
formatted = formatToPostgresTimestamp(each.toString());
137141
}
@@ -141,11 +145,11 @@ private void writeTextValue(final PostgreSQLPacketPayload payload, final Object
141145
} else if (Types.TIMESTAMP_WITH_TIMEZONE == columnType) {
142146
String formatted = "";
143147
if (each instanceof LocalDateTime) {
144-
formatted = DATE_TIME_FORMATTER.format(((LocalDateTime) each).atZone(getSessionZone(sessionTimeZone)));
148+
formatted = DATE_TIME_FORMATTER.format(((LocalDateTime) each).atZone(sessionTimeZone));
145149
} else if (each instanceof OffsetDateTime) {
146-
formatted = DATE_TIME_FORMATTER.format((OffsetDateTime) each);
150+
formatted = DATE_TIME_FORMATTER.format(((OffsetDateTime) each).toInstant().atZone(sessionTimeZone));
147151
} else if (each instanceof Timestamp) {
148-
formatted = DATE_TIME_FORMATTER.format(((Timestamp) each).toLocalDateTime().atZone(getSessionZone(sessionTimeZone)));
152+
formatted = DATE_TIME_FORMATTER.format(((Timestamp) each).toLocalDateTime().atZone(sessionTimeZone));
149153
} else {
150154
formatted = formatToPostgresTimestamp(each.toString());
151155
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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+
package org.apache.shardingsphere.database.protocol.postgresql.packet.command.query;
19+
20+
import org.apache.shardingsphere.database.connector.core.resultset.ResultSetMapper;
21+
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
22+
import org.apache.shardingsphere.database.protocol.postgresql.payload.PostgreSQLPacketPayload;
23+
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
24+
import org.junit.jupiter.api.Test;
25+
import org.junit.jupiter.api.extension.ExtendWith;
26+
import org.mockito.ArgumentCaptor;
27+
import org.mockito.junit.jupiter.MockitoExtension;
28+
import org.mockito.junit.jupiter.MockitoSettings;
29+
import org.mockito.quality.Strictness;
30+
31+
import java.nio.charset.StandardCharsets;
32+
import java.sql.ResultSet;
33+
import java.sql.ResultSetMetaData;
34+
import java.sql.Types;
35+
import java.time.OffsetDateTime;
36+
import java.util.Collections;
37+
38+
import static org.hamcrest.MatcherAssert.assertThat;
39+
import static org.hamcrest.Matchers.is;
40+
import static org.mockito.Mockito.mock;
41+
import static org.mockito.Mockito.verify;
42+
import static org.mockito.Mockito.when;
43+
44+
@ExtendWith(MockitoExtension.class)
45+
@MockitoSettings(strictness = Strictness.LENIENT)
46+
class PostgreSQLDataRowPacketResultSetMapperITTest {
47+
48+
@Test
49+
void assertTimestampTzValueFromResultSetMapperIsWrittenByDataRowPacketAsText() throws Exception {
50+
ResultSet resultSet = mock(ResultSet.class);
51+
ResultSetMetaData metaData = mock(ResultSetMetaData.class);
52+
when(resultSet.getMetaData()).thenReturn(metaData);
53+
54+
when(metaData.getColumnType(1)).thenReturn(Types.TIMESTAMP_WITH_TIMEZONE);
55+
56+
OffsetDateTime expected = OffsetDateTime.parse("2020-01-01T10:20:30+08:00");
57+
when(resultSet.getObject(1)).thenReturn(expected);
58+
when(resultSet.wasNull()).thenReturn(false);
59+
60+
DatabaseType postgreSQL = TypedSPILoader.getService(DatabaseType.class, "PostgreSQL");
61+
Object mapped = new ResultSetMapper(postgreSQL).load(resultSet, 1);
62+
PostgreSQLPacketPayload payload = mock(PostgreSQLPacketPayload.class);
63+
when(payload.getCharset()).thenReturn(StandardCharsets.UTF_8);
64+
PostgreSQLDataRowPacket packet = new PostgreSQLDataRowPacket(Collections.singleton(mapped), Collections.singleton(Types.TIMESTAMP_WITH_TIMEZONE), "+05:30");
65+
packet.write(payload);
66+
67+
byte[] expectedBytes = "2020-01-01 07:50:30+05:30".getBytes(StandardCharsets.UTF_8);
68+
69+
verify(payload).writeInt2(1);
70+
verify(payload).writeInt4(expectedBytes.length);
71+
72+
ArgumentCaptor<byte[]> bytesCaptor = ArgumentCaptor.forClass(byte[].class);
73+
verify(payload).writeBytes(bytesCaptor.capture());
74+
assertThat(bytesCaptor.getValue(), is(expectedBytes));
75+
}
76+
77+
}

database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/packet/command/query/PostgreSQLDataRowPacketTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -214,20 +214,20 @@ void assertWriteWithOffsetDateTime() {
214214
Types.TIMESTAMP_WITH_TIMEZONE,
215215
Types.TIMESTAMP_WITH_TIMEZONE,
216216
Types.TIMESTAMP_WITH_TIMEZONE)),
217-
"Asia/Kolkata");
217+
"+05:30");
218218
actual.write(payload);
219219
InOrder inOrder = Mockito.inOrder(payload);
220-
ZoneOffset systemOffset = ZoneId.of("Asia/Kolkata").getRules()
220+
ZoneOffset systemOffset = ZoneId.of("+05:30").getRules()
221221
.getOffset(LocalDateTime.of(2022, 10, 12, 10, 0, 0, 123_456_000));
222-
byte[] res1 = "2022-10-12 10:00:00+05:30:01".getBytes(StandardCharsets.UTF_8);
222+
byte[] res1 = "2022-10-12 09:59:59+05:30".getBytes(StandardCharsets.UTF_8);
223223
byte[] res2 = "2022-10-12 10:00:00.1+05:30".getBytes(StandardCharsets.UTF_8);
224224
byte[] res3 = "2022-10-12 10:00:00.123456+05:30".getBytes(StandardCharsets.UTF_8);
225-
byte[] res4 = "2022-10-12 10:00:00.12345+02:30".getBytes(StandardCharsets.UTF_8);
225+
byte[] res4 = "2022-10-12 13:00:00.12345+05:30".getBytes(StandardCharsets.UTF_8);
226226
byte[] res5 = ("2022-10-12 10:00:00.123456" + systemOffset.getId()).getBytes(StandardCharsets.UTF_8);
227-
byte[] res6 = "2022-10-12 10:00:00-02:30".getBytes(StandardCharsets.UTF_8);
227+
byte[] res6 = "2022-10-12 18:00:00+05:30".getBytes(StandardCharsets.UTF_8);
228228
byte[] res7 = "2022-10-12 10:00:00.12+00:00".getBytes(StandardCharsets.UTF_8);
229229
byte[] res8 = "2022-10-12 10:00:00+00:00".getBytes(StandardCharsets.UTF_8);
230-
byte[] res9 = ("2022-10-12 10:00:00.123456" + systemOffset).getBytes(StandardCharsets.UTF_8);
230+
byte[] res9 = ("2022-10-12 10:00:00.123456" + systemOffset.getId()).getBytes(StandardCharsets.UTF_8);
231231

232232
inOrder.verify(payload).writeInt4(res1.length);
233233
inOrder.verify(payload).writeBytes(res1);
@@ -270,13 +270,13 @@ void assertWriteWithOffsetTime() {
270270
Types.TIME_WITH_TIMEZONE,
271271
Types.TIME_WITH_TIMEZONE,
272272
Types.TIME_WITH_TIMEZONE)),
273-
"Asia/Kolkata");
273+
"+05:30");
274274
actual.write(payload);
275275
InOrder inOrder = Mockito.inOrder(payload);
276-
ZoneOffset systemOffset = ZoneId.of("Asia/Kolkata").getRules()
276+
ZoneOffset systemOffset = ZoneId.of("+05:30").getRules()
277277
.getOffset(LocalTime.of(10, 0, 12, 123_000_000).atDate(LocalDate.now()));
278278
byte[] res1 = "10:00:00+05:30".getBytes(StandardCharsets.UTF_8);
279-
byte[] res2 = "10:00:00.1-02:30".getBytes(StandardCharsets.UTF_8);
279+
byte[] res2 = "18:00:00.1+05:30".getBytes(StandardCharsets.UTF_8);
280280
byte[] res3 = "10:00:00.1+05:30".getBytes(StandardCharsets.UTF_8);
281281
byte[] res4 = "10:00:00.123456+05:30".getBytes(StandardCharsets.UTF_8);
282282
byte[] res5 = "10:00:00.12345+05:30".getBytes(StandardCharsets.UTF_8);

0 commit comments

Comments
 (0)