Skip to content

Commit

Permalink
fix: add varbit as a basic type inside the TypeInfoCache (#2960)
Browse files Browse the repository at this point in the history
Currently, extra queries are needed to resolve type information for the
varbit type, even though the OID and type information are entirely
predictable. This patch will adds the builtin type into the TypeInfoCache,
to avoid extra round trips on high latency connections.

Fixes: #2959
  • Loading branch information
fqazi committed Oct 6, 2023
1 parent d55de08 commit 9bc47ec
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ public class TypeInfoCache implements TypeInfo {
{"char", Oid.CHAR, Types.CHAR, "java.lang.String", Oid.CHAR_ARRAY},
{"bpchar", Oid.BPCHAR, Types.CHAR, "java.lang.String", Oid.BPCHAR_ARRAY},
{"varchar", Oid.VARCHAR, Types.VARCHAR, "java.lang.String", Oid.VARCHAR_ARRAY},
{"varbit", Oid.VARBIT, Types.OTHER, "java.lang.String", Oid.VARBIT_ARRAY},
{"text", Oid.TEXT, Types.VARCHAR, "java.lang.String", Oid.TEXT_ARRAY},
{"name", Oid.NAME, Types.VARCHAR, "java.lang.String", Oid.NAME_ARRAY},
{"bytea", Oid.BYTEA, Types.BINARY, "[B", Oid.BYTEA_ARRAY},
Expand Down
32 changes: 21 additions & 11 deletions pgjdbc/src/test/java/org/postgresql/jdbc/BitFieldTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@ private static class TestData {
private final String bitValue;
private final String tableName;
private final String tableFields;
private final boolean isVarBit;

TestData(String bitValue, String tableName, String tableFields) {
TestData(String bitValue, String tableName, String tableFields, boolean isVarBit) {
this.bitValue = bitValue;
this.tableName = tableName;
this.tableFields = tableFields;
this.isVarBit = isVarBit;
}

public String getBitValue() {
Expand All @@ -43,17 +45,25 @@ public String getTableName() {
public String getTableFields() {
return tableFields;
}

public boolean getIsVarBit() {
return isVarBit;
}
}

private static final String fieldName = "field_bit";
public static final String testBitValue = "0101010100101010101010100101";
private static final TestData[] testBitValues = new TestData[]{
new TestData("0", "test_bit_field_0a", fieldName + " bit"),
new TestData("0", "test_bit_field_0b", fieldName + " bit(1)"),
new TestData("1", "test_bit_field_1a", fieldName + " bit"),
new TestData("1", "test_bit_field_1b", fieldName + " bit(1)"),
new TestData("0", "test_bit_field_0a", fieldName + " bit", false),
new TestData("0", "test_bit_field_0b", fieldName + " bit(1)", false),
new TestData("1", "test_bit_field_1a", fieldName + " bit", false),
new TestData("1", "test_bit_field_1b", fieldName + " bit(1)", false),
new TestData(testBitValue, "test_bit_field_gt1_1", String.format("%s bit(%d)", fieldName,
testBitValue.length()))
testBitValue.length()), false),
new TestData(testBitValue, "test_varbit_field_gt1_1", String.format("%s varbit(%d)", fieldName,
testBitValue.length()), true),
new TestData("1", "test_varbit_field_1", String.format("%s varbit(1)", fieldName), true),
new TestData("0", "test_varbit_field_0", String.format("%s varbit(1)", fieldName), true)
};

@Override
Expand Down Expand Up @@ -85,7 +95,7 @@ public void TestGetObjectForBitFields() throws SQLException {
for (TestData testData : testBitValues) {
PreparedStatement pstmt = con.prepareStatement(String.format("SELECT field_bit FROM %s "
+ "limit 1", testData.getTableName()));
checkBitFieldValue(pstmt, testData.getBitValue());
checkBitFieldValue(pstmt, testData.getBitValue(), testData.getIsVarBit());
pstmt.close();
}
}
Expand All @@ -98,18 +108,18 @@ public void TestSetBitParameter() throws SQLException {
+ "field_bit = ?");
PGobject param = new PGobject();
param.setValue(testData.getBitValue());
param.setType("bit");
param.setType(testData.getIsVarBit() ? "varbit" : "bit");
pstmt.setObject(1, param);
checkBitFieldValue(pstmt, testData.getBitValue());
checkBitFieldValue(pstmt, testData.getBitValue(), testData.getIsVarBit());
pstmt.close();
}
}

private void checkBitFieldValue(PreparedStatement pstmt, String bitValue) throws SQLException {
private void checkBitFieldValue(PreparedStatement pstmt, String bitValue, boolean isVarBit) throws SQLException {
ResultSet rs = pstmt.executeQuery();
Assert.assertTrue(rs.next());
Object o = rs.getObject(1);
if (bitValue.length() == 1) {
if (bitValue.length() == 1 && !isVarBit) {
Assert.assertTrue("Failed for " + bitValue, o instanceof java.lang.Boolean);
Boolean b = (Boolean) o;
Assert.assertEquals("Failed for " + bitValue, bitValue.charAt(0) == '1', b);
Expand Down

0 comments on commit 9bc47ec

Please sign in to comment.