Search in sources :

Example 1 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class AbstractTypedElementDefinition method mapDefinedType.

static DataTypeDefinition mapDefinedType(Definition container, Definition child, DataTypeDefinition definedType) {
    DataTypeDefinition result = definedType;
    Database db = container.getDatabase();
    log.debug("Type mapping", child + " with type " + definedType.getType());
    // [#976] Mapping DATE as TIMESTAMP
    if (db.dateAsTimestamp()) {
        DataType<?> dataType = null;
        try {
            dataType = DefaultDataType.getDataType(db.getDialect(), result.getType(), 0, 0);
        } catch (SQLDialectNotSupportedException ignore) {
        }
        if (dataType != null) {
            if (dataType.getSQLType() == Types.DATE) {
                DataType<?> forcedDataType = DefaultDataType.getDataType(db.getDialect(), SQLDataType.TIMESTAMP.getTypeName(), 0, 0);
                result = new DefaultDataTypeDefinition(db, child.getSchema(), forcedDataType.getTypeName(), 0, 0, 0, result.isNullable(), result.getDefaultValue(), (Name) null, null, DateAsTimestampBinding.class.getName());
            }
        }
    }
    // [#677] Forced types for matching regular expressions
    ForcedType forcedType = db.getConfiguredForcedType(child, definedType);
    if (forcedType != null) {
        String uType = forcedType.getName();
        String converter = null;
        String binding = result.getBinding();
        CustomType customType = customType(db, forcedType);
        if (customType != null) {
            uType = (!StringUtils.isBlank(customType.getType())) ? customType.getType() : customType.getName();
            if (Boolean.TRUE.equals(customType.isEnumConverter())) {
                String tType = DefaultDataType.getDataType(db.getDialect(), definedType.getType(), definedType.getPrecision(), definedType.getScale()).getType().getName();
                converter = "new " + EnumConverter.class.getName() + "<" + tType + ", " + uType + ">(" + tType + ".class, " + uType + ".class)";
            } else if (!StringUtils.isBlank(customType.getConverter())) {
                converter = customType.getConverter();
            }
            if (!StringUtils.isBlank(customType.getBinding()))
                binding = customType.getBinding();
        }
        if (uType != null) {
            log.info("Forcing type", child + " with type " + definedType.getType() + " into " + uType + (converter != null ? " using converter " + converter : "") + (binding != null ? " using binding " + binding : ""));
            DataType<?> forcedDataType = null;
            boolean n = result.isNullable();
            String d = result.getDefaultValue();
            int l = 0;
            int p = 0;
            int s = 0;
            // [#2486] Allow users to override length, precision, and scale
            Matcher matcher = LENGTH_PRECISION_SCALE_PATTERN.matcher(uType);
            if (matcher.find()) {
                if (!isEmpty(matcher.group(1))) {
                    l = p = convert(matcher.group(1), int.class);
                } else {
                    p = convert(matcher.group(2), int.class);
                    s = convert(matcher.group(3), int.class);
                }
            }
            try {
                forcedDataType = DefaultDataType.getDataType(db.getDialect(), uType, p, s);
            } catch (SQLDialectNotSupportedException ignore) {
            }
            // [#677] SQLDataType matches are actual type-rewrites
            if (forcedDataType != null) {
                result = new DefaultDataTypeDefinition(db, child.getSchema(), uType, l, p, s, n, d, (Name) null, converter, binding);
            } else // Other forced types are UDT's, enums, etc.
            if (customType != null) {
                l = result.getLength();
                p = result.getPrecision();
                s = result.getScale();
                String t = result.getType();
                Name u = result.getQualifiedUserType();
                result = new DefaultDataTypeDefinition(db, child.getSchema(), t, l, p, s, n, d, u, converter, binding, uType);
            } else // [#4597] If we don't have a type-rewrite (forcedDataType) or a
            //         matching customType, the user probably malconfigured
            //         their <forcedTypes/> or <customTypes/>
            {
                StringWriter writer = new StringWriter();
                JAXB.marshal(forcedType, writer);
                log.warn("Bad configuration for <forcedType/> " + forcedType.getName() + ". No matching <customType/> found, and no matching SQLDataType found: " + writer);
            }
        }
    }
    return result;
}
Also used : CustomType(org.jooq.util.jaxb.CustomType) ForcedType(org.jooq.util.jaxb.ForcedType) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) Matcher(java.util.regex.Matcher) Name(org.jooq.Name) StringWriter(java.io.StringWriter) EnumConverter(org.jooq.impl.EnumConverter)

Example 2 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class JavaGenerator method getType.

protected String getType(Database db, SchemaDefinition schema, String t, int p, int s, Name u, String javaType, String defaultType, Mode udtMode) {
    String type = defaultType;
    // Custom types
    if (javaType != null) {
        type = javaType;
    } else // Array types
    if (db.isArrayType(t)) {
        // [#4388] TODO: Improve array handling
        Name baseType = GenerationUtil.getArrayBaseType(db.getDialect(), t, u);
        if (scala)
            type = "scala.Array[" + getType(db, schema, baseType.last(), p, s, baseType, javaType, defaultType, udtMode) + "]";
        else
            type = getType(db, schema, baseType.last(), p, s, baseType, javaType, defaultType, udtMode) + "[]";
    } else // Check for Oracle-style VARRAY types
    if (db.getArray(schema, u) != null) {
        boolean udtArray = db.getArray(schema, u).getElementType().isUDT();
        if (udtMode == Mode.POJO || (udtMode == Mode.INTERFACE && !udtArray)) {
            if (scala)
                type = "java.util.List[" + getJavaType(db.getArray(schema, u).getElementType(), udtMode) + "]";
            else
                type = "java.util.List<" + getJavaType(db.getArray(schema, u).getElementType(), udtMode) + ">";
        } else if (udtMode == Mode.INTERFACE) {
            if (scala)
                type = "java.util.List[_ <:" + getJavaType(db.getArray(schema, u).getElementType(), udtMode) + "]";
            else
                type = "java.util.List<? extends " + getJavaType(db.getArray(schema, u).getElementType(), udtMode) + ">";
        } else {
            type = getStrategy().getFullJavaClassName(db.getArray(schema, u), Mode.RECORD);
        }
    } else // Check for ENUM types
    if (db.getEnum(schema, u) != null) {
        type = getStrategy().getFullJavaClassName(db.getEnum(schema, u));
    } else // Check for UDTs
    if (db.getUDT(schema, u) != null) {
        type = getStrategy().getFullJavaClassName(db.getUDT(schema, u), udtMode);
    } else // [#5334] In MySQL, the user type is (ab)used for synthetic enum types. This can lead to accidental matches here
    if (db.getDialect().family() == POSTGRES && db.getTable(schema, u) != null) {
        type = getStrategy().getFullJavaClassName(db.getTable(schema, u), udtMode);
    } else // Check for custom types
    if (u != null && db.getConfiguredCustomType(u.last()) != null) {
        type = u.last();
    } else // Try finding a basic standard SQL type according to the current dialect
    {
        try {
            Class<?> clazz = mapJavaTimeTypes(DefaultDataType.getDataType(db.getDialect(), t, p, s)).getType();
            if (scala && clazz == byte[].class)
                type = "scala.Array[scala.Byte]";
            else
                type = clazz.getCanonicalName();
            if (clazz.getTypeParameters().length > 0) {
                type += (scala ? "[" : "<");
                String separator = "";
                for (TypeVariable<?> var : clazz.getTypeParameters()) {
                    type += separator;
                    type += ((Class<?>) var.getBounds()[0]).getCanonicalName();
                    separator = ", ";
                }
                type += (scala ? "]" : ">");
            }
        } catch (SQLDialectNotSupportedException e) {
            if (defaultType == null) {
                throw e;
            }
        }
    }
    return type;
}
Also used : SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) StringUtils.defaultString(org.jooq.tools.StringUtils.defaultString) Name(org.jooq.Name)

Example 3 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class InsertQueryImpl method accept0.

@Override
final void accept0(Context<?> ctx) {
    // ------------------------------
    if (onDuplicateKeyUpdate) {
        switch(ctx.family()) {
            // MySQL has a nice syntax for this
            case CUBRID:
            case MARIADB:
            case MYSQL:
                {
                    toSQLInsert(ctx);
                    ctx.formatSeparator().start(INSERT_ON_DUPLICATE_KEY_UPDATE).keyword("on duplicate key update").formatIndentStart().formatSeparator().visit(updateMap).formatIndentEnd().end(INSERT_ON_DUPLICATE_KEY_UPDATE);
                    break;
                }
            case POSTGRES:
                {
                    toSQLInsert(ctx);
                    ctx.formatSeparator().start(INSERT_ON_DUPLICATE_KEY_UPDATE).keyword("on conflict").sql(" (");
                    if (onConflict != null && onConflict.size() > 0) {
                        boolean qualify = ctx.qualify();
                        ctx.qualify(false).visit(onConflict).qualify(qualify);
                    } else if (table.getPrimaryKey() == null) {
                        ctx.sql("[unknown primary key]");
                    } else {
                        boolean qualify = ctx.qualify();
                        ctx.qualify(false).visit(new Fields<Record>(table.getPrimaryKey().getFields())).qualify(qualify);
                    }
                    ctx.sql(") ").keyword("do update").formatSeparator().keyword("set").sql(' ').formatIndentLockStart().visit(updateMap).formatIndentLockEnd();
                    if (!(condition.getWhere() instanceof TrueCondition))
                        ctx.formatSeparator().keyword("where").sql(' ').visit(condition);
                    ctx.end(INSERT_ON_DUPLICATE_KEY_UPDATE);
                    break;
                }
            // Some dialects can't really handle this clause. Emulation should be done in two steps
            case H2:
                {
                    throw new SQLDialectNotSupportedException("The ON DUPLICATE KEY UPDATE clause cannot be emulated for " + ctx.dialect());
                }
            case HSQLDB:
                {
                    ctx.visit(toMerge(ctx.configuration()));
                    break;
                }
            default:
                throw new SQLDialectNotSupportedException("The ON DUPLICATE KEY UPDATE clause cannot be emulated for " + ctx.dialect());
        }
    } else // ------------------------------
    if (onDuplicateKeyIgnore) {
        switch(ctx.dialect()) {
            // MySQL has a nice, native syntax for this
            case MARIADB:
            case MYSQL:
            case SQLITE:
                {
                    toSQLInsert(ctx);
                    ctx.start(INSERT_ON_DUPLICATE_KEY_UPDATE).end(INSERT_ON_DUPLICATE_KEY_UPDATE);
                    break;
                }
            case POSTGRES_9_5:
            case POSTGRES:
                {
                    toSQLInsert(ctx);
                    ctx.formatSeparator().start(INSERT_ON_DUPLICATE_KEY_UPDATE).keyword("on conflict").sql(' ');
                    if (onConflict != null && onConflict.size() > 0) {
                        boolean qualify = ctx.qualify();
                        ctx.sql('(').qualify(false).visit(onConflict).qualify(qualify).sql(") ");
                    }
                    ctx.keyword("do nothing").end(INSERT_ON_DUPLICATE_KEY_UPDATE);
                    break;
                }
            // CUBRID can emulate this using ON DUPLICATE KEY UPDATE
            case CUBRID:
                {
                    FieldMapForUpdate update = new FieldMapForUpdate(INSERT_ON_DUPLICATE_KEY_UPDATE_ASSIGNMENT);
                    Field<?> field = table.field(0);
                    update.put(field, field);
                    toSQLInsert(ctx);
                    ctx.formatSeparator().start(INSERT_ON_DUPLICATE_KEY_UPDATE).keyword("on duplicate key update").sql(' ').visit(update).end(INSERT_ON_DUPLICATE_KEY_UPDATE);
                    break;
                }
            case HSQLDB:
                {
                    ctx.visit(toMerge(ctx.configuration()));
                    break;
                }
            default:
                {
                    ctx.visit(toInsertSelect(ctx.configuration()));
                    break;
                }
        }
    } else // Default mode
    // ------------
    {
        toSQLInsert(ctx);
        ctx.start(INSERT_ON_DUPLICATE_KEY_UPDATE).end(INSERT_ON_DUPLICATE_KEY_UPDATE);
    }
    ctx.start(INSERT_RETURNING);
    toSQLReturning(ctx);
    ctx.end(INSERT_RETURNING);
}
Also used : SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) Tools.aliasedFields(org.jooq.impl.Tools.aliasedFields)

Example 4 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class JavaGenerator method getTypeReference.

protected String getTypeReference(Database db, SchemaDefinition schema, JavaWriter out, String t, int p, int s, int l, boolean n, boolean i, boolean r, String g, GenerationOption go, String d, Name u) {
    StringBuilder sb = new StringBuilder();
    if (db.getArray(schema, u) != null) {
        ArrayDefinition array = database.getArray(schema, u);
        sb.append(getJavaTypeReference(db, array.getElementType(resolver(out)), out));
        sb.append(array.getIndexType() != null ? ".asAssociativeArrayDataType(" : ".asArrayDataType(");
        sb.append(classOf(getStrategy().getFullJavaClassName(array, Mode.RECORD)));
        sb.append(")");
    } else if (db.getDomain(schema, u) != null) {
        sb.append(getStrategy().getFullJavaIdentifier(db.getDomain(schema, u)));
        sb.append(".getDataType()");
    } else if (db.getUDT(schema, u) != null) {
        sb.append(getStrategy().getFullJavaIdentifier(db.getUDT(schema, u)));
        sb.append(".getDataType()");
    } else // [#5334] In MySQL, the user type is (ab)used for synthetic enum types. This can lead to accidental matches here
    if (SUPPORT_TABLE_AS_UDT.contains(db.getDialect()) && db.getTable(schema, u) != null) {
        sb.append(getStrategy().getFullJavaIdentifier(db.getTable(schema, u)));
        sb.append(".getDataType()");
    } else if (db.getEnum(schema, u) != null) {
        sb.append(getJavaTypeReference(db, new DefaultDataTypeDefinition(db, schema, DefaultDataType.getDataType(db.getDialect(), String.class).getTypeName(), l, p, s, n, d, (Name) null), out));
        sb.append(".asEnumDataType(");
        sb.append(classOf(getStrategy().getFullJavaClassName(db.getEnum(schema, u), Mode.ENUM)));
        sb.append(")");
    } else {
        DataType<?> dataType;
        String sqlDataTypeRef;
        try {
            dataType = mapJavaTimeTypes(getDataType(db, t, p, s));
        }// Mostly because of unsupported data types.
         catch (SQLDialectNotSupportedException ignore) {
            dataType = SQLDataType.OTHER.nullable(n).identity(i);
            sb = new StringBuilder();
            sb.append(DefaultDataType.class.getName());
            sb.append(".getDefaultDataType(\"");
            sb.append(escapeString(u != null ? u.toString() : t));
            sb.append("\")");
        }
        dataType = dataType.nullable(n).identity(i);
        if (d != null)
            dataType = dataType.defaultValue((Field) DSL.field(d, dataType));
        // specific DataType t, then reference that one.
        if (dataType.getSQLDataType() != null && sb.length() == 0) {
            DataType<?> sqlDataType = dataType.getSQLDataType();
            String literal = SQLDATATYPE_LITERAL_LOOKUP.get(sqlDataType);
            sqlDataTypeRef = out.ref(SQLDataType.class) + '.' + (literal == null ? "OTHER" : literal);
            sb.append(sqlDataTypeRef);
            if (dataType.hasPrecision() && (dataType.isTimestamp() || p > 0)) {
                // [#6411] Call static method if available, rather than instance method
                if (SQLDATATYPE_WITH_PRECISION.contains(literal))
                    sb.append('(').append(p);
                else
                    sb.append(".precision(").append(p);
                if (dataType.hasScale() && s > 0)
                    sb.append(", ").append(s);
                sb.append(')');
            }
            if (dataType.hasLength() && l > 0)
                // [#6411] Call static method if available, rather than instance method
                if (SQLDATATYPE_WITH_LENGTH.contains(literal))
                    sb.append("(").append(l).append(")");
                else
                    sb.append(".length(").append(l).append(")");
        } else {
            sqlDataTypeRef = SQLDataType.class.getCanonicalName() + ".OTHER";
            if (sb.length() == 0)
                sb.append(sqlDataTypeRef);
        }
        if (!dataType.nullable())
            sb.append(".nullable(false)");
        if (dataType.identity())
            sb.append(".identity(true)");
        // report actual values (e.g. MySQL).
        if (dataType.defaulted()) {
            sb.append(".defaultValue(");
            if (asList(MYSQL).contains(db.getDialect().family()))
                // a CURRENT_TIMESTAMP expression, inconsistently
                if (d != null && d.toLowerCase(getStrategy().getTargetLocale()).startsWith("current_timestamp"))
                    sb.append(out.ref(DSL.class)).append(".field(\"").append(escapeString(d)).append("\"");
                else
                    sb.append(out.ref(DSL.class)).append(".inline(\"").append(escapeString(d)).append("\"");
            else
                sb.append(out.ref(DSL.class)).append(".field(\"").append(escapeString(d)).append("\"");
            sb.append(", ").append(sqlDataTypeRef).append(")").append(kotlin && dataType.getType() == Object.class ? " as Any?" : "").append(")");
        }
    }
    return sb.toString();
}
Also used : SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) SQLDataType(org.jooq.impl.SQLDataType) DefaultDataTypeDefinition(org.jooq.meta.DefaultDataTypeDefinition) ArrayDefinition(org.jooq.meta.ArrayDefinition) DSL(org.jooq.impl.DSL)

Example 5 with SQLDialectNotSupportedException

use of org.jooq.exception.SQLDialectNotSupportedException in project jOOQ by jOOQ.

the class MetaDataFieldProvider method init.

private static FieldsImpl<Record> init(Configuration configuration, ResultSetMetaData meta) {
    Field<?>[] fields;
    int columnCount = 0;
    try {
        columnCount = meta.getColumnCount();
        fields = new Field[columnCount];
    }// procedures / functions
     catch (SQLException e) {
        log.info("Cannot fetch column count for cursor : " + e.getMessage());
        fields = new Field[] { field("dummy") };
    }
    try {
        for (int i = 1; i <= columnCount; i++) {
            Name name;
            String columnLabel = meta.getColumnLabel(i);
            String columnName = meta.getColumnName(i);
            if (Objects.equals(columnName, columnLabel)) {
                try {
                    String columnSchema = meta.getSchemaName(i);
                    String columnTable = meta.getTableName(i);
                    // [#6691] Prevent excessive String[] allocations if names are unqualified / partially qualified
                    if (!StringUtils.isEmpty(columnSchema))
                        name = name(columnSchema, columnTable, columnName);
                    else if (!StringUtils.isEmpty(columnTable))
                        name = name(columnTable, columnName);
                    else
                        name = name(columnName);
                }// ResultSetMetaData.getSchemaName and/or ResultSetMetaData.getTableName methods
                 catch (SQLException e) {
                    name = name(columnLabel);
                }
            } else {
                name = name(columnLabel);
            }
            int precision = meta.getPrecision(i);
            int scale = meta.getScale(i);
            DataType<?> dataType = SQLDataType.OTHER;
            String type = meta.getColumnTypeName(i);
            try {
                dataType = DefaultDataType.getDataType(configuration.family(), type, precision, scale, !FALSE.equals(configuration.settings().isForceIntegerTypesOnZeroScaleDecimals()));
                if (dataType.hasPrecision())
                    dataType = dataType.precision(precision);
                if (dataType.hasScale())
                    dataType = dataType.scale(scale);
                // JDBC doesn't distinguish between precision and length
                if (dataType.hasLength())
                    dataType = dataType.length(precision);
            }// types (e.g. such as PostgreSQL's json type) will cause this exception.
             catch (SQLDialectNotSupportedException e) {
                log.debug("Not supported by dialect", e.getMessage());
            }
            fields[i - 1] = field(name, dataType);
        }
    } catch (SQLException e) {
        throw Tools.translate(null, e);
    }
    return new FieldsImpl<>(fields);
}
Also used : Field(org.jooq.Field) SQLDialectNotSupportedException(org.jooq.exception.SQLDialectNotSupportedException) SQLException(java.sql.SQLException) Name(org.jooq.Name)

Aggregations

SQLDialectNotSupportedException (org.jooq.exception.SQLDialectNotSupportedException)8 Name (org.jooq.Name)4 Matcher (java.util.regex.Matcher)2 SQLDialect (org.jooq.SQLDialect)2 EnumConverter (org.jooq.impl.EnumConverter)2 StringWriter (java.io.StringWriter)1 BigDecimal (java.math.BigDecimal)1 BigInteger (java.math.BigInteger)1 Date (java.sql.Date)1 SQLException (java.sql.SQLException)1 Time (java.sql.Time)1 Timestamp (java.sql.Timestamp)1 LocalDate (java.time.LocalDate)1 LocalDateTime (java.time.LocalDateTime)1 LocalTime (java.time.LocalTime)1 OffsetDateTime (java.time.OffsetDateTime)1 OffsetTime (java.time.OffsetTime)1 UUID (java.util.UUID)1 Configuration (org.jooq.Configuration)1 Converter (org.jooq.Converter)1