Skip to content

Commit

Permalink
apacheGH-35916 [Java][arrow-jdbc] Add extra fields to JdbcFieldInfo (a…
Browse files Browse the repository at this point in the history
…pache#37123)

### Rationale for this change

Existing info is not enough to make completely accurate conversion decisions.

### What changes are included in this PR?

Include the type name reported by the database and the max number of characters as part of the `JdbcFieldInfo`.
* Closes: apache#35916

Authored-by: Diego Fernandez <[email protected]>
Signed-off-by: David Li <[email protected]>
  • Loading branch information
aiguofer authored Aug 14, 2023
1 parent c9d4685 commit b97e526
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package org.apache.arrow.adapter.jdbc;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Types;
Expand All @@ -40,6 +41,8 @@ public class JdbcFieldInfo {
private final int nullability;
private final int precision;
private final int scale;
private final String typeName;
private final int displaySize;

/**
* Builds a <code>JdbcFieldInfo</code> using only the {@link java.sql.Types} type. Do not use this constructor
Expand All @@ -53,12 +56,13 @@ public JdbcFieldInfo(int jdbcType) {
Preconditions.checkArgument(
(jdbcType != Types.DECIMAL && jdbcType != Types.NUMERIC),
"DECIMAL and NUMERIC types require a precision and scale; please use another constructor.");

this.column = 0;
this.jdbcType = jdbcType;
this.nullability = ResultSetMetaData.columnNullableUnknown;
this.precision = 0;
this.scale = 0;
this.typeName = "";
this.displaySize = 0;
}

/**
Expand All @@ -75,6 +79,8 @@ public JdbcFieldInfo(int jdbcType, int precision, int scale) {
this.nullability = ResultSetMetaData.columnNullableUnknown;
this.precision = precision;
this.scale = scale;
this.typeName = "";
this.displaySize = 0;
}

/**
Expand All @@ -92,6 +98,8 @@ public JdbcFieldInfo(int jdbcType, int nullability, int precision, int scale) {
this.nullability = nullability;
this.precision = precision;
this.scale = scale;
this.typeName = "";
this.displaySize = 0;
}

/**
Expand All @@ -115,6 +123,25 @@ public JdbcFieldInfo(ResultSetMetaData rsmd, int column) throws SQLException {
this.nullability = rsmd.isNullable(column);
this.precision = rsmd.getPrecision(column);
this.scale = rsmd.getScale(column);
this.typeName = rsmd.getColumnTypeName(column);
this.displaySize = rsmd.getColumnDisplaySize(column);
}

/**
* Builds a <code>JdbcFieldInfo</code> from the corresponding row from a {@link java.sql.DatabaseMetaData#getColumns}
* ResulSet.
*
* @param rs The {@link java.sql.ResultSet} to get the field information from.
* @throws SQLException If the column information cannot be retrieved.
*/
public JdbcFieldInfo(ResultSet rs) throws SQLException {
this.column = rs.getInt("ORDINAL_POSITION");
this.jdbcType = rs.getInt("DATA_TYPE");
this.nullability = rs.getInt("NULLABLE");
this.precision = rs.getInt("COLUMN_SIZE");
this.scale = rs.getInt("DECIMAL_DIGITS");
this.typeName = rs.getString("TYPE_NAME");
this.displaySize = rs.getInt("CHAR_OCTET_LENGTH");
}

/**
Expand Down Expand Up @@ -151,4 +178,18 @@ public int getScale() {
public int getColumn() {
return column;
}

/**
* The type name as reported by the database.
*/
public String getTypeName() {
return typeName;
}

/**
* The max number of characters for the column.
*/
public int getDisplaySize() {
return displaySize;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,16 @@ public int isNullable(int column) throws SQLException {
return columns.get(column - 1).isNullable();
}

@Override
public int getColumnDisplaySize(int column) throws SQLException {
return columns.get(column - 1).getDisplaySize();
}

@Override
public String getColumnTypeName(int column) throws SQLException {
return columns.get(column - 1).getTypeName();
}

public static MockResultSetMetaData fromRows(ArrayList<MockRow> rows) throws SQLException {
// Note: This attempts to dynamically construct ResultSetMetaData from the first row in a given result set.
// If there are now rows, or the result set contains no columns, this cannot be dynamically generated and
Expand All @@ -334,6 +344,8 @@ public static class MockColumnMetaData {
private int scale;
private int nullable;
private String label;
private String typeName;
private int displaySize;


private MockColumnMetaData() {}
Expand Down Expand Up @@ -362,13 +374,23 @@ private int isNullable() {
return nullable;
}

private String getTypeName() {
return typeName;
}

private int getDisplaySize() {
return displaySize;
}

public static MockColumnMetaData fromDataElement(MockDataElement element, int i) throws SQLException {
return MockColumnMetaData.builder()
.index(i)
.sqlType(element.getSqlType())
.precision(element.getPrecision())
.scale(element.getScale())
.nullable(element.isNullable())
.setTypeName("TYPE")
.setDisplaySize(420)
.label("col_" + i)
.build();
}
Expand Down Expand Up @@ -410,6 +432,16 @@ public Builder nullable(int nullable) {
return this;
}

public Builder setTypeName(String typeName) {
this.columnMetaData.typeName = typeName;
return this;
}

public Builder setDisplaySize(int displaySize) {
this.columnMetaData.displaySize = displaySize;
return this;
}

public MockColumnMetaData build() {
return this.columnMetaData;
}
Expand Down

0 comments on commit b97e526

Please sign in to comment.