提交 e4760bbd authored 作者: Thomas Mueller's avatar Thomas Mueller

PgServer: incorrect SQL types were returned in result set meta data.

上级 481585be
......@@ -45,9 +45,14 @@ public class PgServer implements Service {
*/
public static final int DEFAULT_PORT = 5435;
/**
* The VARCHAR type.
*/
public static final int PG_TYPE_VARCHAR = 1043;
private static final int PG_TYPE_BOOL = 16;
private static final int PG_TYPE_BYTEA = 17;
private static final int PG_TYPE_CHAR = 18;
private static final int PG_TYPE_BPCHAR = 1042;
private static final int PG_TYPE_INT8 = 20;
private static final int PG_TYPE_INT2 = 21;
private static final int PG_TYPE_INT4 = 23;
......@@ -57,12 +62,13 @@ public class PgServer implements Service {
private static final int PG_TYPE_FLOAT8 = 701;
private static final int PG_TYPE_UNKNOWN = 705;
private static final int PG_TYPE_TEXTARRAY = 1009;
private static final int PG_TYPE_VARCHAR = 1043;
private static final int PG_TYPE_DATE = 1082;
private static final int PG_TYPE_TIME = 1083;
private static final int PG_TYPE_TIMESTAMP_NO_TMZONE = 1114;
private static final int PG_TYPE_NUMERIC = 1700;
private HashSet<Integer> typeSet = New.hashSet();
private int port = PgServer.DEFAULT_PORT;
private boolean stop;
private boolean trace;
......@@ -102,8 +108,8 @@ public class PgServer implements Service {
}
}
org.h2.Driver.load();
// int testing;
// log = true;
// int testing;
// trace = true;
}
boolean getTrace() {
......@@ -410,7 +416,7 @@ public class PgServer implements Service {
case Types.CLOB:
return PG_TYPE_TEXT;
case Types.CHAR:
return PG_TYPE_CHAR;
return PG_TYPE_BPCHAR;
case Types.SMALLINT:
return PG_TYPE_INT2;
case Types.INTEGER:
......@@ -440,4 +446,25 @@ public class PgServer implements Service {
}
}
/**
* Get the type hash set.
*
* @return the type set
*/
HashSet<Integer> getTypeSet() {
return typeSet;
}
/**
* Check whether a data type is supported.
* A warning is logged if not.
*
* @param type the type
*/
void checkType(int type) {
if (!typeSet.contains(type)) {
trace("Unsupported type: " + type);
}
}
}
......@@ -43,7 +43,6 @@ import org.h2.util.ScriptReader;
* One server thread is opened for each client.
*/
public class PgServerThread implements Runnable {
private static final int TYPE_STRING = Types.VARCHAR;
private PgServer server;
private Socket socket;
private Connection conn;
......@@ -63,7 +62,6 @@ public class PgServerThread implements Runnable {
private String dateStyle = "ISO";
private HashMap<String, Prepared> prepared = New.hashMap();
private HashMap<String, Portal> portals = New.hashMap();
private HashSet<Integer> typeSet = New.hashSet();
PgServerThread(Socket socket, PgServer server) {
this.server = server;
......@@ -163,7 +161,7 @@ public class PgServerThread implements Runnable {
} else if ("DateStyle".equals(param)) {
dateStyle = value;
}
// server.log(" param " + param + "=" + value);
server.trace(" param " + param + "=" + value);
}
sendAuthenticationCleartextPassword();
initDone = true;
......@@ -210,7 +208,7 @@ public class PgServerThread implements Runnable {
p.paramType = new int[count];
for (int i = 0; i < count; i++) {
int type = readInt();
checkType(type);
server.checkType(type);
p.paramType[i] = type;
}
try {
......@@ -373,12 +371,6 @@ public class PgServerThread implements Runnable {
}
}
private void checkType(int type) {
if (typeSet.contains(type)) {
server.trace("Unsupported type: " + type);
}
}
private String getSQL(String s) {
String lower = s.toLowerCase();
if (lower.startsWith("show max_identifier_length")) {
......@@ -495,9 +487,9 @@ public class PgServerThread implements Runnable {
if (p.paramType != null && p.paramType[i] != 0) {
type = p.paramType[i];
} else {
type = TYPE_STRING;
type = PgServer.PG_TYPE_VARCHAR;
}
checkType(type);
server.checkType(type);
writeInt(type);
}
sendMessage();
......@@ -523,8 +515,9 @@ public class PgServerThread implements Runnable {
for (int i = 0; i < columns; i++) {
names[i] = meta.getColumnName(i + 1);
int type = meta.getColumnType(i + 1);
type = PgServer.convertType(type);
precision[i] = meta.getColumnDisplaySize(i + 1);
checkType(type);
server.checkType(type);
types[i] = type;
}
startMessage('T');
......@@ -588,37 +581,42 @@ public class PgServerThread implements Runnable {
ResultSet rs = null;
Reader r = null;
try {
rs = conn.getMetaData().getTables(null, "PG_CATALOG", "PG_VERSION", null);
boolean tableFound = rs.next();
stat = conn.createStatement();
if (tableFound) {
rs = stat.executeQuery("SELECT VERSION FROM PG_CATALOG.PG_VERSION");
if (rs.next()) {
if (rs.getInt(1) == 1) {
// already installed
stat.execute("set search_path = PUBLIC, pg_catalog");
return;
synchronized (server) {
// better would be: set the database to exclusive mode
rs = conn.getMetaData().getTables(null, "PG_CATALOG", "PG_VERSION", null);
boolean tableFound = rs.next();
stat = conn.createStatement();
if (!tableFound) {
try {
r = new InputStreamReader(new ByteArrayInputStream(Resources
.get("/org/h2/server/pg/pg_catalog.sql")));
} catch (IOException e) {
throw Message.convertIOException(e, "Can not read pg_catalog resource");
}
ScriptReader reader = new ScriptReader(r);
while (true) {
String sql = reader.readStatement();
if (sql == null) {
break;
}
stat.execute(sql);
}
reader.close();
}
}
try {
r = new InputStreamReader(new ByteArrayInputStream(Resources.get("/org/h2/server/pg/pg_catalog.sql")));
} catch (IOException e) {
throw Message.convertIOException(e, "Can not read pg_catalog resource");
}
ScriptReader reader = new ScriptReader(r);
while (true) {
String sql = reader.readStatement();
if (sql == null) {
break;
}
stat.execute(sql);
rs = stat.executeQuery("SELECT VERSION FROM PG_CATALOG.PG_VERSION");
if (!rs.next() || rs.getInt(1) != 1) {
throw Message.throwInternalError("Invalid PG_VERSION");
}
reader.close();
stat.execute("set search_path = PUBLIC, pg_catalog");
rs = stat.executeQuery("SELECT OID FROM PG_CATALOG.PG_TYPE");
while (rs.next()) {
typeSet.add(rs.getInt(1));
HashSet<Integer> typeSet = server.getTypeSet();
if (typeSet.size() == 0) {
rs = stat.executeQuery("SELECT OID FROM PG_CATALOG.PG_TYPE");
while (rs.next()) {
typeSet.add(rs.getInt(1));
}
}
} finally {
JdbcUtils.closeSilently(stat);
......
......@@ -12,8 +12,10 @@ import java.sql.DriverManager;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import org.h2.test.TestBase;
import org.h2.tools.Server;
......@@ -68,6 +70,11 @@ public class TestPgServer extends TestBase {
prep.execute();
ResultSet rs = stat.executeQuery("select * from test");
rs.next();
ResultSetMetaData rsMeta = rs.getMetaData();
assertEquals(Types.INTEGER, rsMeta.getColumnType(1));
assertEquals(Types.VARCHAR, rsMeta.getColumnType(2));
prep.close();
assertEquals(1, rs.getInt(1));
assertEquals("Hello", rs.getString(2));
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论