From b17543d032711de1a58fcf5005b21330a738d7bd Mon Sep 17 00:00:00 2001 From: Alexandr Varyanik Date: Tue, 11 May 2021 16:46:05 +0300 Subject: [PATCH] 0004345: Postgres array types improperly cast into non-array types (#122) * 0004345: add json and jsonb column type support for PostgreSqlDmlStatement * refactor methods for parameters appending from PostgreSqlDmlStatement * 0004345: add array column type support for PostgreSqlDmlStatement --- .../java/org/jumpmind/db/model/TypeMap.java | 4 +- .../postgresql/PostgreSqlDmlStatement.java | 65 +++++++++++-------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/symmetric-db/src/main/java/org/jumpmind/db/model/TypeMap.java b/symmetric-db/src/main/java/org/jumpmind/db/model/TypeMap.java index fc1497375d..9541750ff7 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/model/TypeMap.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/model/TypeMap.java @@ -118,7 +118,9 @@ public abstract class TypeMap public static final String IMAGE = "IMAGE"; public static final String DATETIME2 = "DATETIME2"; public static final String TSVECTOR = "TSVECTOR"; - + public static final String JSONB = "JSONB"; + public static final String JSON = "JSON"; + /** Maps type names to the corresponding {@link java.sql.Types} constants. */ private static HashMap _typeNameToTypeCode = new HashMap(); diff --git a/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement.java b/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement.java index 9a018d6af4..c5900fd748 100644 --- a/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement.java +++ b/symmetric-db/src/main/java/org/jumpmind/db/platform/postgresql/PostgreSqlDmlStatement.java @@ -124,20 +124,14 @@ protected int[] buildTypes(Column[] keys, Column[] columns, boolean isDateOverri @Override protected void appendColumnParameter(StringBuilder sql, Column column) { - if (column.isTimestampWithTimezone()) { - sql.append("cast(? as timestamp with time zone)").append(","); - } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.UUID)) { - sql.append("cast(? as uuid)").append(","); - } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.VARBIT)) { - sql.append("cast(? as bit varying)").append(","); - } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.INTERVAL)) { - sql.append("cast(? as interval)").append(","); + String typeToCast = getTypeToCast(column); + + if (typeToCast != null) { + sql.append("cast(? as ").append(typeToCast).append(")").append(","); } else if (column.getJdbcTypeName() != null && ( column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOMETRY) || column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOGRAPHY))) { sql.append("ST_GEOMFROMTEXT(?)").append(","); - } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.TSVECTOR)) { - sql.append("cast(? as tsvector)").append(","); } else { super.appendColumnParameter(sql, column); } @@ -145,29 +139,46 @@ protected void appendColumnParameter(StringBuilder sql, Column column) { @Override protected void appendColumnEquals(StringBuilder sql, Column column) { - if (column.isTimestampWithTimezone()) { - sql.append(quote).append(column.getName()).append(quote) - .append(" = cast(? as timestamp with time zone)"); - } else if (column.getJdbcTypeName().toUpperCase().contains(TypeMap.UUID)) { - sql.append(quote).append(column.getName()).append(quote) - .append(" = cast(? as uuid)"); - } else if (column.getJdbcTypeName().toUpperCase().contains(TypeMap.VARBIT)) { - sql.append(quote).append(column.getName()).append(quote) - .append(" = cast(? as bit varying)"); - } else if (column.getJdbcTypeName().toUpperCase().contains(TypeMap.INTERVAL)) { - sql.append(quote).append(column.getName()).append(quote) - .append(" = cast(? as interval)"); - } else if (column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOMETRY) || - column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOGRAPHY)) { + String typeToCast = getTypeToCast(column); + + if (typeToCast != null) { sql.append(quote).append(column.getName()).append(quote) - .append(" = ST_GEOMFROMTEXT(?)"); - } else if (column.getJdbcTypeName().toUpperCase().contains(TypeMap.TSVECTOR)) { - sql.append(quote).append(column.getName()).append(quote).append(" = cast(? as tsvector)"); + .append(" = cast(? as ").append(typeToCast).append(")").append(","); + } else if (column.getJdbcTypeName() != null && ( + column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOMETRY) || + column.getJdbcTypeName().toUpperCase().contains(TypeMap.GEOGRAPHY))) { + sql.append(" = ST_GEOMFROMTEXT(?)"); } else { super.appendColumnEquals(sql, column); } } + private String getTypeToCast(Column column) { + String typeToCast = null; + + if (column.isTimestampWithTimezone()) { + typeToCast = "timestamp with time zone"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.UUID)) { + typeToCast = "uuid"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.VARBIT)) { + typeToCast = "bit varying"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.INTERVAL)) { + typeToCast = "interval"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.TSVECTOR)) { + typeToCast = "tsvector"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.JSONB)) { + typeToCast = "json"; + } else if (column.getJdbcTypeName() != null && column.getJdbcTypeName().toUpperCase().contains(TypeMap.JSON)) { + typeToCast = "json"; + } + + if (typeToCast != null && column.getMappedType() != null && column.getMappedType().equals(TypeMap.ARRAY)) { + typeToCast = typeToCast + "[]"; + } + + return typeToCast; + } + @Override protected void appendColumnNameForSql(StringBuilder sql, Column column, boolean select) { String columnName = column.getName();