diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index c0079b92e6..59dd7615fc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -60,10 +60,12 @@ import static org.jooq.SQLDialect.POSTGRES; import static org.jooq.SQLDialect.SQLITE; // ... // ... +import static org.jooq.conf.BackslashEscaping.ON; import static org.jooq.conf.ParamType.NAMED; import static org.jooq.conf.ParamType.NAMED_OR_INLINED; import static org.jooq.impl.DSL.name; import static org.jooq.impl.DSL.using; +import static org.jooq.impl.Utils.settings; import static org.jooq.tools.StringUtils.leftPad; import java.math.BigDecimal; @@ -82,6 +84,7 @@ import org.jooq.RenderContext; import org.jooq.SQLDialect; import org.jooq.Schema; import org.jooq.UDTRecord; +import org.jooq.conf.BackslashEscaping; import org.jooq.tools.StringUtils; import org.jooq.types.Interval; @@ -408,7 +411,7 @@ class Val extends AbstractParam { // Interval extends Number, so let Interval come first! else if (Interval.class.isAssignableFrom(type)) { context.sql("'") - .sql(escape(val)) + .sql(escape(val, context)) .sql("'"); } @@ -423,7 +426,7 @@ class Val extends AbstractParam { // The SQLite JDBC driver does not implement the escape syntax // [#1253] SQL Server and Sybase do not implement date literals if (asList(SQLITE).contains(family)) { - context.sql("'").sql(escape(val)).sql("'"); + context.sql("'").sql(escape(val, context)).sql("'"); } /* [pro] xx @@ -432,23 +435,23 @@ class Val extends AbstractParam { x xxxx xx xxxxxxx xx xxxxxxxxx x - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxx x xx [/pro] */ // [#1253] Derby doesn't support the standard literal else if (family == DERBY) { - context.keyword("date('").sql(escape(val)).sql("')"); + context.keyword("date('").sql(escape(val, context)).sql("')"); } // [#3648] Circumvent a MySQL bug related to date literals else if (family == MYSQL) { - context.keyword("{d '").sql(val.toString()).sql("'}"); + context.keyword("{d '").sql(escape(val, context)).sql("'}"); } // Most dialects implement SQL standard date literals else { - context.keyword("date '").sql(escape(val)).sql("'"); + context.keyword("date '").sql(escape(val, context)).sql("'"); } } else if (type == Timestamp.class) { @@ -456,7 +459,7 @@ class Val extends AbstractParam { // The SQLite JDBC driver does not implement the escape syntax // [#1253] SQL Server and Sybase do not implement timestamp literals if (asList(SQLITE).contains(family)) { - context.sql("'").sql(escape(val)).sql("'"); + context.sql("'").sql(escape(val, context)).sql("'"); } /* [pro] xx @@ -465,28 +468,28 @@ class Val extends AbstractParam { x xxxx xx xxxxxxx xx xxxxxxxxx x - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxxxxxxx x xx [/pro] */ // [#1253] Derby doesn't support the standard literal else if (family == DERBY) { - context.keyword("timestamp('").sql(escape(val)).sql("')"); + context.keyword("timestamp('").sql(escape(val, context)).sql("')"); } // CUBRID timestamps have no fractional seconds else if (family == CUBRID) { - context.keyword("datetime '").sql(escape(val)).sql("'"); + context.keyword("datetime '").sql(escape(val, context)).sql("'"); } // [#3648] Circumvent a MySQL bug related to date literals else if (family == MYSQL) { - context.keyword("{ts '").sql(val.toString()).sql("'}"); + context.keyword("{ts '").sql(escape(val, context)).sql("'}"); } // Most dialects implement SQL standard timestamp literals else { - context.keyword("timestamp '").sql(escape(val)).sql("'"); + context.keyword("timestamp '").sql(escape(val, context)).sql("'"); } } else if (type == Time.class) { @@ -499,33 +502,33 @@ class Val extends AbstractParam { /* [pro] xx xxxx xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x - xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxxx x xxxx xx xxxxxxx xx xxxxxxxxx x - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xx xxxxxxxxx x xx [/pro] */ // [#1253] Derby doesn't support the standard literal else if (family == DERBY) { - context.keyword("time").sql("('").sql(escape(val)).sql("')"); + context.keyword("time").sql("('").sql(escape(val, context)).sql("')"); } // [#3648] Circumvent a MySQL bug related to date literals else if (family == MYSQL) { - context.keyword("{t '").sql(val.toString()).sql("'}"); + context.keyword("{t '").sql(escape(val, context)).sql("'}"); } /* [pro] xx xx xxxxxxx xxxxxx xxxxxxx xxxx xxxx xxxxxxxx xxxx xx xxxxxxx xx xxxxxxx x - xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxx + xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxx xxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxxxx x xx [/pro] */ // Most dialects implement SQL standard time literals else { - context.keyword("time").sql(" '").sql(escape(val)).sql("'"); + context.keyword("time").sql(" '").sql(escape(val, context)).sql("'"); } } else if (type.isArray()) { @@ -566,7 +569,7 @@ class Val extends AbstractParam { } /* [pro] xx xxxx xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x - xxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxx + xxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxx xxxxxx x xx [/pro] */ else if (EnumType.class.isAssignableFrom(type)) { @@ -589,7 +592,7 @@ class Val extends AbstractParam { // - UUID else { context.sql("'") - .sql(escape(val), true) + .sql(escape(val, context), true) .sql("'"); } } @@ -636,10 +639,16 @@ class Val extends AbstractParam { } /** - * Escape a string literal by replacing ' by '' + * Escape a string literal by replacing ' by '', and possibly also backslashes. */ - private final String escape(Object val) { - return val.toString().replace("'", "''"); + private final String escape(Object val, Context context) { + BackslashEscaping escaping = settings(context.configuration()).getBackslashEscaping(); + String result = val.toString(); + + if (escaping == ON) + result = result.replace("\\", "\\\\"); + + return result.replace("'", "''"); } final void bind0(BindContext context) { diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.5.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.5.0.xsd index 0840766acd..37ef467a1a 100644 --- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.5.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.5.0.xsd @@ -33,6 +33,9 @@ Oracle 11g (and potentially, other databases too) implements scalar subquery caching. With this flag set to true, users can automatically profit from this feature in all SQL statements. --> + + + + + + + + + + + \ No newline at end of file