--- old/src/java.sql/share/classes/java/sql/Statement.java 2015-10-20 18:38:52.000000000 -0400 +++ new/src/java.sql/share/classes/java/sql/Statement.java 2015-10-20 18:38:51.000000000 -0400 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ package java.sql; +import java.util.regex.Pattern; +import static java.util.stream.Collectors.joining; + /** *

The object used for executing a static SQL statement * and returning the results it produces. @@ -1367,4 +1370,154 @@ throws SQLException { throw new SQLFeatureNotSupportedException("executeLargeUpdate not implemented"); } + + // JDBC 4.3 + + /** + * Returns a {@code String} enclosed in single quotes. Any occurrence of a + * single quote within the string will be replaced by two single quotes. + *

+ *

+ * + * + * + * + * + * + * + * + * + * + *
Examples of the conversion:
ValueResult
Hello 'Hello'
G'Day 'G''Day'
'G''Day''''G''''Day'''
I'''M 'I''''''M'
+ *
+ * @implNote + * JDBC driver implementations may need to provide their own implementation + * of this method in order to meet the requirements of the underlying + * datasource. + * @param val a character string + * @return A string enclosed by single quotes with every single quote + * converted to two single quotes + * @throws NullPointerException if val is null + */ + default String enquoteLiteral(String val) { + return "'" + val.replace("'", "''") + "'"; + } + + + /** + * Returns a SQL identifier. If {@code identifier} is a simple SQL identifier: + * + * + * If {@code identifier} is not a simple SQL identifier, {@code identifier} will be + * enclosed in double quotes if not already present. If the datasource does + * not support double quotes for delimited identifiers, the + * identifier should be enclosed by the string returned from + * {@link DatabaseMetaData#getIdentifierQuoteString}. If the datasource + * does not support delimited identifiers, a + * {@code SQLFeatureNotSupportedException} should be thrown. + *

+ * A {@code SQLException} will be thrown if {@code identifier} contains any + * characters invalid in a delimited identifier or the identifier length is + * invalid for the datasource. + * + * @implSpec + * The default implementation uses the following criteria to + * determine a valid simple SQL identifier: + *

+ * + * The default implementation will throw a {@code SQLException} if: + * + *
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Examples of the conversion:
identifieralwaysQuoteResult
HellofalseHello
Hellotrue"Hello"
G'Dayfalse"G'Day"
"Bruce Wayne"false"Bruce Wayne"
"Bruce Wayne"true"Bruce Wayne"
GoodDay$false"GoodDay$"
Hello"WorldfalseSQLException
"Hello"World"falseSQLException
+ *
+ * @implNote + * JDBC driver implementations may need to provide their own implementation + * of this method in order to meet the requirements of the underlying + * datasource. + * @param identifier a SQL identifier + * @param alwaysQuote indicates if a simple SQL identifier should be + * returned as a quoted identifier + * @return A simple SQL identifier or a delimited identifier + * @throws SQLException if identifier is not a valid identifier + * @throws SQLFeatureNotSupportedException if the datasource does not support + * delimited identifiers + * @throws NullPointerException if identifier is null + */ + default String enquoteIdentifier(String identifier, boolean alwaysQuote) throws SQLException { + int len = identifier.length(); + if (len < 1 || len > 128) { + throw new SQLException("Invalid name"); + } + if (Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]+").matcher(identifier).matches()) { + return alwaysQuote ? "\"" + identifier + "\"" : identifier; + } + if (identifier.matches("^\".+\"$")) { + identifier = identifier.substring(1, len - 1); + } + if (Pattern.compile("[^\u0000\"]+").matcher(identifier).matches()) { + return "\"" + identifier + "\""; + } else { + throw new SQLException("Invalid name"); + } + } }