Skip to content

Commit

Permalink
feat: add smallserial metadata (pgjdbc#899)
Browse files Browse the repository at this point in the history
PostgreSQL 9.2 adds a SMALLSERIAL data type, this reports the correct metadata information when a column is a smallserial (int2 with sequence), similar to how a serial or bigserial data types are reported.
  • Loading branch information
jorsol committed Sep 30, 2020
1 parent 2393241 commit 2c02d4e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 11 deletions.
14 changes: 10 additions & 4 deletions pgjdbc/src/main/java/org/postgresql/jdbc/PgDatabaseMetaData.java
Original file line number Diff line number Diff line change
Expand Up @@ -1609,7 +1609,7 @@ public ResultSet getColumns(@Nullable String catalog, @Nullable String schemaPat
tuple[5] = connection.encodeString("serial"); // Type name == serial
} else if ("int8".equals(pgType)) {
tuple[5] = connection.encodeString("bigserial"); // Type name == bigserial
} else if ("int2".equals(pgType)) {
} else if ("int2".equals(pgType) && connection.haveMinimumServerVersion(ServerVersion.v9_2)) {
tuple[5] = connection.encodeString("smallserial"); // Type name == smallserial
}
}
Expand Down Expand Up @@ -2372,19 +2372,25 @@ public ResultSet getTypeInfo() throws SQLException {
tuple[17] = b10; // everything is base 10
v.add(new Tuple(tuple));

// add pseudo-type serial, bigserial
if (typname.equals("int4")) {
// add pseudo-type serial, bigserial, smallserial
if ("int4".equals(typname)) {
byte[] @Nullable [] tuple1 = tuple.clone();

tuple1[0] = connection.encodeString("serial");
tuple1[11] = bt;
v.add(new Tuple(tuple1));
} else if (typname.equals("int8")) {
} else if ("int8".equals(typname)) {
byte[] @Nullable [] tuple1 = tuple.clone();

tuple1[0] = connection.encodeString("bigserial");
tuple1[11] = bt;
v.add(new Tuple(tuple1));
} else if ("int2".equals(typname) && connection.haveMinimumServerVersion(ServerVersion.v9_2)) {
byte[] @Nullable [] tuple1 = tuple.clone();

tuple1[0] = connection.encodeString("smallserial");
tuple1[11] = bt;
v.add(new Tuple(tuple1));
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ public String getColumnTypeName(int column) throws SQLException {
return "serial";
} else if ("int8".equals(type)) {
return "bigserial";
} else if ("int2".equals(type) && connection.haveMinimumServerVersion(ServerVersion.v9_2)) {
return "smallserial";
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ public void setUp() throws Exception {
"id int4, name text, updated timestamptz, colour text, quest text");
TestUtil.dropSequence(con, "sercoltest_b_seq");
TestUtil.dropSequence(con, "sercoltest_c_seq");
TestUtil.dropSequence(con, "sercoltest_s_seq");
TestUtil.createTable(con, "sercoltest", "a int, b serial, c bigserial, s smallserial");
TestUtil.createTable(con, "sercoltest", "a int, b serial, c bigserial");
TestUtil.createTable(con, "\"a\\\"", "a int4");
TestUtil.createTable(con, "\"a'\"", "a int4");
TestUtil.createTable(con, "arraytable", "a numeric(5,2)[], b varchar(100)[]");
Expand Down Expand Up @@ -129,7 +128,6 @@ public void tearDown() throws Exception {
TestUtil.dropTable(con, "sercoltest");
TestUtil.dropSequence(con, "sercoltest_b_seq");
TestUtil.dropSequence(con, "sercoltest_c_seq");
TestUtil.dropSequence(con, "sercoltest_s_seq");
TestUtil.dropTable(con, "\"a\\\"");
TestUtil.dropTable(con, "\"a'\"");
TestUtil.dropTable(con, "arraytable");
Expand Down Expand Up @@ -583,14 +581,11 @@ public void testSerialColumns() throws SQLException {
} else if (rownum == 2) {
assertEquals("bigserial", rs.getString("TYPE_NAME"));
assertTrue(rs.getBoolean("IS_AUTOINCREMENT"));
} else if (rownum == 3 ) {
assertEquals("smallserial", rs.getString("TYPE_NAME"));
assertTrue(rs.getBoolean("IS_AUTOINCREMENT"));
}

rownum++;
}
assertEquals(4, rownum);
assertEquals(3, rownum);
rs.close();
}

Expand Down Expand Up @@ -1493,4 +1488,56 @@ public void testFunctionColumns() throws SQLException {

rs.close();
}

@Test
public void testSmallSerialColumns() throws SQLException {
org.junit.Assume.assumeTrue(TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_2));
TestUtil.createTable(con, "smallserial_test", "a smallserial");

DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getColumns(null, null, "smallserial_test", "a");
assertTrue(rs.next());
assertEquals("smallserial_test", rs.getString("TABLE_NAME"));
assertEquals("a", rs.getString("COLUMN_NAME"));
assertEquals(Types.SMALLINT, rs.getInt("DATA_TYPE"));
assertEquals("smallserial", rs.getString("TYPE_NAME"));
assertTrue(rs.getBoolean("IS_AUTOINCREMENT"));
assertEquals("nextval('smallserial_test_a_seq'::regclass)", rs.getString("COLUMN_DEF"));
assertFalse(rs.next());
rs.close();

TestUtil.dropTable(con, "smallserial_test");
}

@Test
public void testSmallSerialSequenceLikeColumns() throws SQLException {
Statement stmt = con.createStatement();
// This is the equivalent of the smallserial, not the actual smallserial
stmt.execute("CREATE SEQUENCE smallserial_test_a_seq;\n"
+ "CREATE TABLE smallserial_test (\n"
+ " a smallint NOT NULL DEFAULT nextval('smallserial_test_a_seq')\n"
+ ");\n"
+ "ALTER SEQUENCE smallserial_test_a_seq OWNED BY smallserial_test.a;");

DatabaseMetaData dbmd = con.getMetaData();
ResultSet rs = dbmd.getColumns(null, null, "smallserial_test", "a");
assertTrue(rs.next());
assertEquals("smallserial_test", rs.getString("TABLE_NAME"));
assertEquals("a", rs.getString("COLUMN_NAME"));
assertEquals(Types.SMALLINT, rs.getInt("DATA_TYPE"));
if (TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_2)) {
// in Pg 9.2+ it behaves like smallserial
assertEquals("smallserial", rs.getString("TYPE_NAME"));
} else {
assertEquals("int2", rs.getString("TYPE_NAME"));
}
assertTrue(rs.getBoolean("IS_AUTOINCREMENT"));
assertEquals("nextval('smallserial_test_a_seq'::regclass)", rs.getString("COLUMN_DEF"));
assertFalse(rs.next());
rs.close();

stmt.execute("DROP TABLE smallserial_test");
stmt.close();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -340,4 +340,50 @@ private void assumePreparedStatementMetadataSupported() {
preferQueryMode.compareTo(PreferQueryMode.EXTENDED_FOR_PREPARED) >= 0);
}

@Test
public void testSmallSerialColumns() throws SQLException {
org.junit.Assume.assumeTrue(TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_2));
TestUtil.createTable(con, "smallserial_test", "a smallserial");

Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT a FROM smallserial_test");
ResultSetMetaData rsmd = rs.getMetaData();
assertTrue(rsmd.isAutoIncrement(1));
assertEquals("smallserial_test", rsmd.getTableName(1));
assertEquals("a", rsmd.getColumnName(1));
assertEquals(Types.SMALLINT, rsmd.getColumnType(1));
assertEquals("smallserial", rsmd.getColumnTypeName(1));
rs.close();

TestUtil.dropTable(con, "smallserial_test");
}

@Test
public void testSmallSerialSequenceLikeColumns() throws SQLException {
Statement stmt = con.createStatement();
// This is the equivalent of the smallserial, not the actual smallserial
stmt.execute("CREATE SEQUENCE smallserial_test_a_seq;\n"
+ "CREATE TABLE smallserial_test (\n"
+ " a smallint NOT NULL DEFAULT nextval('smallserial_test_a_seq')\n"
+ ");\n"
+ "ALTER SEQUENCE smallserial_test_a_seq OWNED BY smallserial_test.a;");

ResultSet rs = stmt.executeQuery("SELECT a FROM smallserial_test");
ResultSetMetaData rsmd = rs.getMetaData();
assertTrue(rsmd.isAutoIncrement(1));
assertEquals("smallserial_test", rsmd.getTableName(1));
assertEquals("a", rsmd.getColumnName(1));
assertEquals(Types.SMALLINT, rsmd.getColumnType(1));
if (TestUtil.haveMinimumServerVersion(con, ServerVersion.v9_2)) {
// in Pg 9.2+ it behaves like smallserial
assertEquals("smallserial", rsmd.getColumnTypeName(1));
} else {
assertEquals("int2", rsmd.getColumnTypeName(1));
}
rs.close();

stmt.execute("DROP TABLE smallserial_test");
stmt.close();
}

}

0 comments on commit 2c02d4e

Please sign in to comment.