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

Handle null date-time values in PgServer

上级 16aa82c5
......@@ -20,6 +20,7 @@ import java.net.Socket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
......@@ -582,36 +583,49 @@ public class PgServerThread implements Runnable {
break;
}
case PgServer.PG_TYPE_DATE: {
writeInt(4);
long millis = rs.getDate(column).getTime();
millis += TimeZone.getDefault().getOffset(millis);
writeInt((int) (toPostgreSeconds(millis) / 86400));
Date d = rs.getDate(column);
if (d == null) {
writeInt(-1);
} else {
writeInt(4);
long millis = d.getTime();
millis += TimeZone.getDefault().getOffset(millis);
writeInt((int) (toPostgreSeconds(millis) / 86400));
}
break;
}
case PgServer.PG_TYPE_TIME: {
writeInt(8);
Time t = rs.getTime(column);
long m = t.getTime();
m += TimeZone.getDefault().getOffset(m);
// double format
m /= 1000;
m = Double.doubleToLongBits(m);
// long format
// m *= 1000;
writeInt((int) (m >>> 32));
writeInt((int) m);
if (t == null) {
writeInt(-1);
} else {
writeInt(8);
long m = t.getTime();
m += TimeZone.getDefault().getOffset(m);
// double format
m /= 1000;
m = Double.doubleToLongBits(m);
// long format
// m *= 1000;
writeInt((int) (m >>> 32));
writeInt((int) m);
}
break;
}
case PgServer.PG_TYPE_TIMESTAMP_NO_TMZONE: {
writeInt(8);
Timestamp t = rs.getTimestamp(column);
long m = t.getTime();
m += TimeZone.getDefault().getOffset(m);
// double format
m = toPostgreSeconds(m);
m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001);
writeInt((int) (m >>> 32));
writeInt((int) m);
if (t == null) {
writeInt(-1);
} else {
writeInt(8);
long m = t.getTime();
m += TimeZone.getDefault().getOffset(m);
// double format
m = toPostgreSeconds(m);
m = Double.doubleToLongBits(m + t.getNanos() * 0.000000001);
writeInt((int) (m >>> 32));
writeInt((int) m);
}
break;
}
default: throw new IllegalStateException("output binary format is undefined");
......
......@@ -56,6 +56,7 @@ public class TestPgServer extends TestBase {
testKeyAlias();
testCancelQuery();
testBinaryTypes();
testDateTime();
testPrepareWithUnspecifiedType();
}
......@@ -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 {
if (!getPgJdbcDriver()) {
return;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论