Search in sources :

Example 1 with PostgresUtils.toPGArrayString

use of org.jooq.util.postgres.PostgresUtils.toPGArrayString in project jOOQ by jOOQ.

the class DefaultBinding method toSQL.

/**
     * Inlining abstraction
     */
@SuppressWarnings({ "unchecked", "rawtypes" })
private final void toSQL(BindingSQLContext<U> ctx, Object val) {
    SQLDialect family = ctx.family();
    RenderContext render = ctx.render();
    if (render.paramType() == INLINED) {
        if (val == null) {
            render.keyword("null");
        } else if (type == Boolean.class) {
            // [#1153] Some dialects don't support boolean literals TRUE and FALSE
            if (asList(FIREBIRD, SQLITE).contains(family)) {
                render.sql(((Boolean) val) ? "1" : "0");
            } else {
                render.keyword(((Boolean) val).toString());
            }
        } else // [#1154] Binary data cannot always be inlined
        if (type == byte[].class) {
            byte[] binary = (byte[]) val;
            if (asList().contains(family)) {
                render.sql("0x").sql(convertBytesToHex(binary));
            } else if (asList(DERBY, H2, HSQLDB, MARIADB, MYSQL, SQLITE).contains(family)) {
                render.sql("X'").sql(convertBytesToHex(binary)).sql('\'');
            } else if (asList().contains(family)) {
                render.keyword("hextoraw('").sql(convertBytesToHex(binary)).sql("')");
            } else if (family == POSTGRES) {
                render.sql("E'").sql(PostgresUtils.toPGString(binary)).keyword("'::bytea");
            } else // This default behaviour is used in debug logging for dialects
            // that do not support inlining binary data
            {
                render.sql("X'").sql(convertBytesToHex(binary)).sql('\'');
            }
        } else // Interval extends Number, so let Interval come first!
        if (Interval.class.isAssignableFrom(type)) {
            render.sql('\'').sql(escape(val, render)).sql('\'');
        } else // [#5249] Special inlining of special floating point values
        if (Double.class.isAssignableFrom(type) && ((Double) val).isNaN()) {
            if (POSTGRES == family)
                render.visit(inline("NaN")).sql("::").keyword("float8");
            else
                render.sql(((Number) val).toString());
        } else // [#5249] Special inlining of special floating point values
        if (Float.class.isAssignableFrom(type) && ((Float) val).isNaN()) {
            if (POSTGRES == family)
                render.visit(inline("NaN")).sql("::").keyword("float4");
            else
                render.sql(((Number) val).toString());
        } else if (Number.class.isAssignableFrom(type)) {
            render.sql(((Number) val).toString());
        } else // [#1156] DATE / TIME inlining is very vendor-specific
        if (Tools.isDate(type)) {
            Date date = getDate(type, val);
            // [#1253] SQL Server and Sybase do not implement date literals
            if (asList(SQLITE).contains(family)) {
                render.sql('\'').sql(escape(date, render)).sql('\'');
            } else // [#1253] Derby doesn't support the standard literal
            if (family == DERBY) {
                render.keyword("date('").sql(escape(date, render)).sql("')");
            } else // [#3648] Circumvent a MySQL bug related to date literals
            if (family == MYSQL) {
                render.keyword("{d '").sql(escape(date, render)).sql("'}");
            } else // Most dialects implement SQL standard date literals
            {
                render.keyword("date '").sql(escape(date, render)).sql('\'');
            }
        } else if (Tools.isTimestamp(type)) {
            Timestamp ts = getTimestamp(type, val);
            // [#1253] SQL Server and Sybase do not implement timestamp literals
            if (asList(SQLITE).contains(family)) {
                render.sql('\'').sql(escape(ts, render)).sql('\'');
            } else // [#1253] Derby doesn't support the standard literal
            if (family == DERBY) {
                render.keyword("timestamp('").sql(escape(ts, render)).sql("')");
            } else // CUBRID timestamps have no fractional seconds
            if (family == CUBRID) {
                render.keyword("datetime '").sql(escape(ts, render)).sql('\'');
            } else // [#3648] Circumvent a MySQL bug related to date literals
            if (family == MYSQL) {
                render.keyword("{ts '").sql(escape(ts, render)).sql("'}");
            } else // Most dialects implement SQL standard timestamp literals
            {
                render.keyword("timestamp '").sql(escape(ts, render)).sql('\'');
            }
        } else if (Tools.isTime(type)) {
            Time time = getTime(type, val);
            // [#1253] SQL Server and Sybase do not implement time literals
            if (asList(SQLITE).contains(family)) {
                render.sql('\'').sql(new SimpleDateFormat("HH:mm:ss").format(time)).sql('\'');
            } else // [#1253] Derby doesn't support the standard literal
            if (family == DERBY) {
                render.keyword("time").sql("('").sql(escape(time, render)).sql("')");
            } else // [#3648] Circumvent a MySQL bug related to date literals
            if (family == MYSQL) {
                render.keyword("{t '").sql(escape(time, render)).sql("'}");
            } else // Most dialects implement SQL standard time literals
            {
                render.keyword("time").sql(" '").sql(escape(time, render)).sql('\'');
            }
        } else if (type == OffsetDateTime.class) {
            String string = format((OffsetDateTime) val);
            // Some dialects implement SQL standard time literals
            {
                render.keyword("timestamp with time zone").sql(" '").sql(escape(string, render)).sql('\'');
            }
        } else if (type == OffsetTime.class) {
            String string = format((OffsetTime) val);
            // Some dialects implement SQL standard time literals
            {
                render.keyword("time with time zone").sql(" '").sql(escape(string, render)).sql('\'');
            }
        } else if (type.isArray()) {
            String separator = "";
            // H2 renders arrays as rows
            if (family == H2) {
                render.sql('(');
                for (Object o : ((Object[]) val)) {
                    render.sql(separator);
                    new DefaultBinding<Object, Object>(Converters.identity((Class) type.getComponentType()), isLob).sql(new DefaultBindingSQLContext<Object>(ctx.configuration(), ctx.data(), ctx.render(), o));
                    separator = ", ";
                }
                render.sql(')');
            } else if (family == POSTGRES) {
                render.visit(cast(inline(PostgresUtils.toPGArrayString((Object[]) val)), type));
            } else // By default, render HSQLDB / POSTGRES syntax
            {
                render.keyword("ARRAY");
                render.sql('[');
                for (Object o : ((Object[]) val)) {
                    render.sql(separator);
                    new DefaultBinding<Object, Object>(Converters.identity((Class) type.getComponentType()), isLob).sql(new DefaultBindingSQLContext<Object>(ctx.configuration(), ctx.data(), ctx.render(), o));
                    separator = ", ";
                }
                render.sql(']');
                // [#3214] Some PostgreSQL array type literals need explicit casting
                if (family == POSTGRES && EnumType.class.isAssignableFrom(type.getComponentType())) {
                    pgRenderEnumCast(render, type);
                }
            }
        } else if (EnumType.class.isAssignableFrom(type)) {
            String literal = ((EnumType) val).getLiteral();
            if (literal == null) {
                new DefaultBinding<Object, Object>(Converters.identity((Class) String.class), isLob).sql(new DefaultBindingSQLContext<Object>(ctx.configuration(), ctx.data(), ctx.render(), literal));
            } else {
                new DefaultBinding<Object, Object>(Converters.identity((Class) String.class), isLob).sql(new DefaultBindingSQLContext<Object>(ctx.configuration(), ctx.data(), ctx.render(), literal));
            }
        } else if (UDTRecord.class.isAssignableFrom(type)) {
            render.sql("[UDT]");
        } else // Known fall-through types:
        // - Blob, Clob (both not supported by jOOQ)
        // - String
        // - UUID
        {
            render.sql('\'').sql(escape(val, render), true).sql('\'');
        }
    } else // In Postgres, some additional casting must be done in some cases...
    if (family == SQLDialect.POSTGRES) {
        // Postgres needs explicit casting for enum (array) types
        if (EnumType.class.isAssignableFrom(type) || (type.isArray() && EnumType.class.isAssignableFrom(type.getComponentType()))) {
            render.sql(ctx.variable());
            pgRenderEnumCast(render, type);
        } else // ... and also for other array types
        if (type.isArray() && byte[].class != type) {
            render.sql(ctx.variable());
            render.sql("::");
            render.keyword(DefaultDataType.getDataType(family, type).getCastTypeName(render.configuration()));
        } else {
            render.sql(ctx.variable());
        }
    } else {
        render.sql(ctx.variable());
    }
}
Also used : RenderContext(org.jooq.RenderContext) Time(java.sql.Time) LocalTime(java.time.LocalTime) OffsetTime(java.time.OffsetTime) OffsetDateTime(java.time.OffsetDateTime) LocalDateTime(java.time.LocalDateTime) PostgresUtils.toPGArrayString(org.jooq.util.postgres.PostgresUtils.toPGArrayString) Timestamp(java.sql.Timestamp) LocalDate(java.time.LocalDate) Date(java.sql.Date) UNumber(org.jooq.types.UNumber) SQLDialect(org.jooq.SQLDialect) OffsetTime(java.time.OffsetTime) EnumType(org.jooq.EnumType) SimpleDateFormat(java.text.SimpleDateFormat) PostgresUtils.toPGInterval(org.jooq.util.postgres.PostgresUtils.toPGInterval) Interval(org.jooq.types.Interval)

Aggregations

Date (java.sql.Date)1 Time (java.sql.Time)1 Timestamp (java.sql.Timestamp)1 SimpleDateFormat (java.text.SimpleDateFormat)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 EnumType (org.jooq.EnumType)1 RenderContext (org.jooq.RenderContext)1 SQLDialect (org.jooq.SQLDialect)1 Interval (org.jooq.types.Interval)1 UNumber (org.jooq.types.UNumber)1 PostgresUtils.toPGArrayString (org.jooq.util.postgres.PostgresUtils.toPGArrayString)1 PostgresUtils.toPGInterval (org.jooq.util.postgres.PostgresUtils.toPGInterval)1