提交 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,36 +583,49 @@ public class PgServerThread implements Runnable { ...@@ -582,36 +583,49 @@ public class PgServerThread implements Runnable {
break; break;
} }
case PgServer.PG_TYPE_DATE: { case PgServer.PG_TYPE_DATE: {
writeInt(4); Date d = rs.getDate(column);
long millis = rs.getDate(column).getTime(); if (d == null) {
millis += TimeZone.getDefault().getOffset(millis); writeInt(-1);
writeInt((int) (toPostgreSeconds(millis) / 86400)); } else {
writeInt(4);
long millis = d.getTime();
millis += TimeZone.getDefault().getOffset(millis);
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);
long m = t.getTime(); if (t == null) {
m += TimeZone.getDefault().getOffset(m); writeInt(-1);
// double format } else {
m /= 1000; writeInt(8);
m = Double.doubleToLongBits(m); long m = t.getTime();
// long format m += TimeZone.getDefault().getOffset(m);
// m *= 1000; // double format
writeInt((int) (m >>> 32)); m /= 1000;
writeInt((int) m); m = Double.doubleToLongBits(m);
// long format
// m *= 1000;
writeInt((int) (m >>> 32));
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);
long m = t.getTime(); if (t == null) {
m += TimeZone.getDefault().getOffset(m); writeInt(-1);
// double format } else {
m = toPostgreSeconds(m); writeInt(8);
m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001); long m = t.getTime();
writeInt((int) (m >>> 32)); m += TimeZone.getDefault().getOffset(m);
writeInt((int) m); // double format
m = toPostgreSeconds(m);
m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001);
writeInt((int) (m >>> 32));
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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论