提交 0010a60f authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Handle null date-time values in PgServer

上级 16aa82c5
...@@ -20,6 +20,7 @@ import java.net.Socket; ...@@ -20,6 +20,7 @@ import java.net.Socket;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Date;
import java.sql.ParameterMetaData; import java.sql.ParameterMetaData;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
...@@ -582,15 +583,23 @@ public class PgServerThread implements Runnable { ...@@ -582,15 +583,23 @@ public class PgServerThread implements Runnable {
break; break;
} }
case PgServer.PG_TYPE_DATE: { case PgServer.PG_TYPE_DATE: {
Date d = rs.getDate(column);
if (d == null) {
writeInt(-1);
} else {
writeInt(4); writeInt(4);
long millis = rs.getDate(column).getTime(); long millis = d.getTime();
millis += TimeZone.getDefault().getOffset(millis); millis += TimeZone.getDefault().getOffset(millis);
writeInt((int) (toPostgreSeconds(millis) / 86400)); writeInt((int) (toPostgreSeconds(millis) / 86400));
}
break; break;
} }
case PgServer.PG_TYPE_TIME: { case PgServer.PG_TYPE_TIME: {
writeInt(8);
Time t = rs.getTime(column); Time t = rs.getTime(column);
if (t == null) {
writeInt(-1);
} else {
writeInt(8);
long m = t.getTime(); long m = t.getTime();
m += TimeZone.getDefault().getOffset(m); m += TimeZone.getDefault().getOffset(m);
// double format // double format
...@@ -600,11 +609,15 @@ public class PgServerThread implements Runnable { ...@@ -600,11 +609,15 @@ public class PgServerThread implements Runnable {
// m *= 1000; // m *= 1000;
writeInt((int) (m >>> 32)); writeInt((int) (m >>> 32));
writeInt((int) m); writeInt((int) m);
}
break; break;
} }
case PgServer.PG_TYPE_TIMESTAMP_NO_TMZONE: { case PgServer.PG_TYPE_TIMESTAMP_NO_TMZONE: {
writeInt(8);
Timestamp t = rs.getTimestamp(column); Timestamp t = rs.getTimestamp(column);
if (t == null) {
writeInt(-1);
} else {
writeInt(8);
long m = t.getTime(); long m = t.getTime();
m += TimeZone.getDefault().getOffset(m); m += TimeZone.getDefault().getOffset(m);
// double format // double format
...@@ -612,6 +625,7 @@ public class PgServerThread implements Runnable { ...@@ -612,6 +625,7 @@ public class PgServerThread implements Runnable {
m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001); m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001);
writeInt((int) (m >>> 32)); writeInt((int) (m >>> 32));
writeInt((int) m); writeInt((int) m);
}
break; break;
} }
default: throw new IllegalStateException("output binary format is undefined"); default: throw new IllegalStateException("output binary format is undefined");
......
...@@ -56,6 +56,7 @@ public class TestPgServer extends TestBase { ...@@ -56,6 +56,7 @@ public class TestPgServer extends TestBase {
testKeyAlias(); testKeyAlias();
testCancelQuery(); testCancelQuery();
testBinaryTypes(); testBinaryTypes();
testDateTime();
testPrepareWithUnspecifiedType(); testPrepareWithUnspecifiedType();
} }
...@@ -451,6 +452,56 @@ public class TestPgServer extends TestBase { ...@@ -451,6 +452,56 @@ public class TestPgServer extends TestBase {
} }
} }
private void testDateTime() throws SQLException, InterruptedException {
if (!getPgJdbcDriver()) {
return;
}
Server server = createPgServer(
"-pgPort", "5535", "-pgDaemon", "-key", "pgserver", "mem:pgserver");
try {
Properties props = new Properties();
props.setProperty("user", "sa");
props.setProperty("password", "sa");
// force binary
props.setProperty("prepareThreshold", "-1");
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5535/pgserver", props);
Statement stat = conn.createStatement();
stat.execute(
"create table test(x1 date, x2 time, x3 timestamp)");
Date[] dates = { null, Date.valueOf("2017-02-20") };
Time[] times = { null, Time.valueOf("14:15:16") };
Timestamp[] timestamps = { null, Timestamp.valueOf("2017-02-20 14:15:16.763") };
int count = dates.length;
PreparedStatement ps = conn.prepareStatement(
"insert into test values (?,?,?)");
for (int i = 0; i < count; i++) {
ps.setDate(1, dates[i]);
ps.setTime(2, times[i]);
ps.setTimestamp(3, timestamps[i]);
ps.execute();
}
ResultSet rs = stat.executeQuery("select * from test");
for (int i = 0; i < count; i++) {
assertTrue(rs.next());
assertEquals(dates[i], rs.getDate(1));
assertEquals(times[i], rs.getTime(2));
assertEquals(timestamps[i], rs.getTimestamp(3));
}
assertFalse(rs.next());
conn.close();
} finally {
server.stop();
}
}
private void testPrepareWithUnspecifiedType() throws Exception { private void testPrepareWithUnspecifiedType() throws Exception {
if (!getPgJdbcDriver()) { if (!getPgJdbcDriver()) {
return; return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论