Skip to content

Commit

Permalink
Remove previous hack around BLOB-LONGVARBINARY for PostgreSQL, and
Browse files Browse the repository at this point in the history
replace with selective artificial handling for BLOB/CLOB so we treat
directly using LongVarBinaryColumnMapping or LongVarcharColumnMapping if
the JDBC driver doesn't provide for them (and hence the user can just
specify "BLOB" or "CLOB" as the JDBC type and not give a monkeys what
the JDBC driver is too lazy to provide for. Fixes #234 (untested). Fixes
#338 (untested).
  • Loading branch information
andyjefferson committed Apr 29, 2020
1 parent 9c00e47 commit 3fc4e94
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,9 @@ protected Collection<SQLTypeInfo> getSQLTypeInfoForJdbcType(StoreSchemaHandler h
* @param jdbcTypeNumber The JDBC type
* @param sqlType The type info to use
* @param addIfNotPresent whether to add only if JDBC type not present
* @return Whether the SQL type for JDBC type was added
*/
protected void addSQLTypeForJDBCType(StoreSchemaHandler handler, ManagedConnection mconn, short jdbcTypeNumber, SQLTypeInfo sqlType, boolean addIfNotPresent)
protected boolean addSQLTypeForJDBCType(StoreSchemaHandler handler, ManagedConnection mconn, short jdbcTypeNumber, SQLTypeInfo sqlType, boolean addIfNotPresent)
{
RDBMSTypesInfo types = (RDBMSTypesInfo)handler.getSchemaData(mconn.getConnection(), "types", null);

Expand All @@ -735,7 +736,7 @@ protected void addSQLTypeForJDBCType(StoreSchemaHandler handler, ManagedConnecti
if (jdbcType != null && !addIfNotPresent)
{
// Already have this JDBC type so ignore
return;
return false;
}
else if (jdbcType == null)
{
Expand All @@ -749,6 +750,7 @@ else if (jdbcType == null)
// Existing JDBC type so add SQL type
jdbcType.addChild(sqlType);
}
return true;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,6 @@ public interface DatastoreAdapter
/** Whether "Types.BIT" is really mapped as BOOLEAN. */
public static final String BIT_IS_REALLY_BOOLEAN = "BitIsReallyBoolean";

/** Whether "Types.BLOB" is really mapped as LONGVARBINARY. */
public static final String BLOB_IS_REALLY_LONGVARBINARY = "BlobIsReallyLongVarBinary";

/** Do we support right outer join? */
public static final String RIGHT_OUTER_JOIN = "RightOuterJoin";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,10 @@ public class PostgreSQLAdapter extends BaseDatastoreAdapter
/** List of Postgresql keywords that aren't in SQL92, SQL99 */
public static final String POSTGRESQL_RESERVED_WORDS =
"ALL,ANALYSE,ANALYZE,DO,FREEZE,ILIKE,ISNULL,OFFSET,PLACING,VERBOSE";

// protected Map<String, String> psqlTypes;

/**
* Constructor.
* @param metadata MetaData for the DB
* @param metadata MetaData from the JDBC driver
*/
public PostgreSQLAdapter(DatabaseMetaData metadata)
{
Expand Down Expand Up @@ -120,9 +118,6 @@ public PostgreSQLAdapter(DatabaseMetaData metadata)

supportedOptions.add(NATIVE_ENUM_TYPE);

// BLOB is not provided via JDBC with PostgreSQL, so we map it to bytea as per LONGVARBINARY
supportedOptions.add(BLOB_IS_REALLY_LONGVARBINARY);

supportedOptions.remove(VALUE_GENERATION_UUID_STRING); // PostgreSQL charsets don't seem to allow this
}

Expand All @@ -137,31 +132,55 @@ public void initialiseTypes(StoreSchemaHandler handler, ManagedConnection mconn)

// Add on any missing JDBC types when not available from driver

// Not present in PSQL 8.1.405
// Add CHAR : Not present in PSQL 8.1.405
SQLTypeInfo sqlType = new PostgreSQLTypeInfo("char", (short)Types.CHAR, 65000, null, null, null, 0, false, (short)3, false, false, false, "char", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.CHAR, sqlType, true);
boolean added = addSQLTypeForJDBCType(handler, mconn, (short)Types.CHAR, sqlType, true);

// Mirrored from LONGVARCHAR ("text") from JDBC driver
// Add CLOB mirrored from LONGVARCHAR ("text") from JDBC driver ** if not provided by the driver **
sqlType = new PostgreSQLTypeInfo("text", (short)Types.CLOB, 0, null, null, null, 1, true, (short)3, true, false, false, "text", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.CLOB, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.CLOB, sqlType, true);
if (added)
{
// Mimic as if LONGVARCHAR
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarcharColumnMapping.class, JDBCType.CLOB, "text", false);
}
else
{
// Support as CLOB since provided by the driver
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.ClobColumnMapping.class, JDBCType.CLOB, "CLOB", false);
}

// Mirrored from LONGVARBINARY ("bytea") from JDBC driver
// Add BLOB mirrored from LONGVARBINARY ("bytea") from JDBC driver ** if not provided by the driver **
sqlType = new PostgreSQLTypeInfo("bytea", (short)Types.BLOB, 0, null, null, null, 1, true, (short)3, true, false, false, "bytea", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.BLOB, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.BLOB, sqlType, true);
if (added)
{
// Mimic as if LONGVARBINARY
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarBinaryColumnMapping.class, JDBCType.BLOB, "bytea", false);
registerColumnMapping(byte[].class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarBinaryColumnMapping.class, JDBCType.BLOB, "bytea", false);
registerColumnMapping(java.io.Serializable.class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarBinaryColumnMapping.class, JDBCType.BLOB, "bytea", false);
}
else
{
// Support as BLOB since provided by the driver
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
registerColumnMapping(byte[].class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
registerColumnMapping(java.io.Serializable.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
}

// Not present in PSQL 9.2.8 - just mirror what BIT does
// Add BOOLEAN : Not present in PSQL 9.2.8 - just mirror what BIT does
sqlType = new PostgreSQLTypeInfo("bool", (short)Types.BOOLEAN, 0, null, null, null, 1, false, (short)3, true, false, false, "bool", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.BOOLEAN, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.BOOLEAN, sqlType, true);

// Not present in PSQL 9.2.8 - just mirror what SMALLINT does
// Add TINYINT : Not present in PSQL 9.2.8 - just mirror what SMALLINT does
sqlType = new PostgreSQLTypeInfo("int2", (short)Types.TINYINT, 0, null, null, null, 1, false, (short)3, false, false, false, "int2", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.TINYINT, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.TINYINT, sqlType, true);

// Not present in PSQL 9.2.8
// Add ARRAY : Not present in PSQL 9.2.8
sqlType = new PostgreSQLTypeInfo("text array", (short)Types.ARRAY, 0, null, null, null, 1, false, (short)3, false, false, false, "text array", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.ARRAY, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.ARRAY, sqlType, true);
sqlType = new PostgreSQLTypeInfo("int array", (short)Types.ARRAY, 0, null, null, null, 1, false, (short)3, false, false, false, "int array", (short)0, (short)0, 10);
addSQLTypeForJDBCType(handler, mconn, (short)Types.ARRAY, sqlType, true);
added = addSQLTypeForJDBCType(handler, mconn, (short)Types.ARRAY, sqlType, true);
}

/**
Expand Down Expand Up @@ -821,11 +840,12 @@ protected void loadColumnMappings(PluginManager mgr, ClassLoaderResolver clr)
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.CharColumnMapping.class, JDBCType.CHAR, "CHAR", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.BigIntColumnMapping.class, JDBCType.BIGINT, "BIGINT", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarcharColumnMapping.class, JDBCType.LONGVARCHAR, "LONGVARCHAR", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.ClobColumnMapping.class, JDBCType.CLOB, "CLOB", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.SqlXmlColumnMapping.class, JDBCType.SQLXML, "SQLXML", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.NVarcharColumnMapping.class, JDBCType.NVARCHAR, "NVARCHAR", false);
registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.NCharColumnMapping.class, JDBCType.NCHAR, "NCHAR", false);
// Added in initialiseTypes dependent on JDBC driver
// registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.ClobColumnMapping.class, JDBCType.CLOB, "CLOB", false);
// registerColumnMapping(String.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);

registerColumnMapping(BigDecimal.class.getName(), org.datanucleus.store.rdbms.mapping.column.NumericColumnMapping.class, JDBCType.NUMERIC, "NUMERIC", true);

Expand Down Expand Up @@ -872,10 +892,12 @@ protected void loadColumnMappings(PluginManager mgr, ClassLoaderResolver clr)
registerColumnMapping(java.util.Collection.class.getName(), org.datanucleus.store.rdbms.mapping.column.ArrayColumnMapping.class, JDBCType.ARRAY, "INT ARRAY", false);

registerColumnMapping(java.io.Serializable.class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarBinaryColumnMapping.class, JDBCType.LONGVARBINARY, "LONGVARBINARY", true);
registerColumnMapping(java.io.Serializable.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
// Added in initialiseTypes dependent on JDBC driver
// registerColumnMapping(java.io.Serializable.class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);

registerColumnMapping(byte[].class.getName(), org.datanucleus.store.rdbms.mapping.column.LongVarBinaryColumnMapping.class, JDBCType.LONGVARBINARY, "LONGVARBINARY", true);
registerColumnMapping(byte[].class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);
// Added in initialiseTypes dependent on JDBC driver
// registerColumnMapping(byte[].class.getName(), org.datanucleus.store.rdbms.mapping.column.BlobColumnMapping.class, JDBCType.BLOB, "BLOB", false);

registerColumnMapping(java.io.File.class.getName(), org.datanucleus.store.rdbms.mapping.column.BinaryStreamColumnMapping.class, JDBCType.LONGVARBINARY, "LONGVARBINARY", true);

Expand Down

0 comments on commit 3fc4e94

Please sign in to comment.