8369432: Add Support for JDBC 4.5 MR

Reviewed-by: alanb, rriggs
This commit is contained in:
Lance Andersen 2025-11-30 12:53:00 +00:00
parent 92e1357dfd
commit 282f339406
27 changed files with 2460 additions and 357 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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
@ -61,13 +61,19 @@ package java.sql;
* If the connection's type map or a type map supplied to a method has no entry
* for the base type, the elements are mapped according to the standard mapping.
* <p>
* To release resources used by the {@code Array} object, applications must call
* either the {@link #free()} or the {@link #close()} method. Any attempt to
* invoke a method other than {@link #free()} or {@link #close()} after the
* {@code Array} object has been closed, will result in a {@link SQLException}
* being thrown.
* <P>
* All methods on the {@code Array} interface must be fully implemented if the
* JDBC driver supports the data type.
*
* @since 1.2
*/
public interface Array {
public interface Array extends AutoCloseable {
/**
* Retrieves the SQL type name of the elements in
@ -345,21 +351,35 @@ public interface Array {
java.util.Map<String,Class<?>> map)
throws SQLException;
/**
* This method frees the {@code Array} object and releases the resources that
* it holds. The object is invalid once the {@code free}
* method is called.
* Closes and releases the resources held by this {@code Array} object.
* <p>
* After {@code free} has been called, any attempt to invoke a
* method other than {@code free} will result in a {@code SQLException}
* being thrown. If {@code free} is called multiple times, the subsequent
* calls to {@code free} are treated as a no-op.
* If the {@code Array} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the Array's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since 1.6
* @see #close()
*/
void free() throws SQLException;
/**
* Closes and releases the resources held by this {@code Array} object.
* <p>
* If the {@code Array} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the Array's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @implSpec The default implementation calls the {@link #free()} method.
* @see #free()
* @since 26
*/
default void close() throws SQLException {
free();
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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
@ -32,7 +32,7 @@ import java.io.InputStream;
* the Java programming language of an SQL
* {@code BLOB} value. An SQL {@code BLOB} is a built-in type
* that stores a Binary Large Object as a column value in a row of
* a database table. By default drivers implement {@code Blob} using
* a database table. By default, drivers implement {@code Blob} using
* an SQL {@code locator(BLOB)}, which means that a
* {@code Blob} object contains a logical pointer to the
* SQL {@code BLOB} data rather than the data itself.
@ -50,13 +50,19 @@ import java.io.InputStream;
* {@code BLOB} value. In addition, this interface has methods for updating
* a {@code BLOB} value.
* <p>
* To release resources used by the {@code Blob} object, applications must call
* either the {@link #free()} or the {@link #close()} method. Any attempt to
* invoke a method other than {@link #free()} or {@link #close()} after the
* {@code Blob} object has been closed, will result in a {@link SQLException}
* being thrown.
* <P>
* All methods on the {@code Blob} interface must be fully implemented if the
* JDBC driver supports the data type.
*
* @since 1.2
*/
public interface Blob {
public interface Blob extends AutoCloseable {
/**
* Returns the number of bytes in the {@code BLOB} value
@ -266,20 +272,17 @@ public interface Blob {
void truncate(long len) throws SQLException;
/**
* This method frees the {@code Blob} object and releases the resources that
* it holds. The object is invalid once the {@code free}
* method is called.
* Closes and releases the resources held by this {@code Blob} object.
* <p>
* After {@code free} has been called, any attempt to invoke a
* method other than {@code free} will result in an {@code SQLException}
* being thrown. If {@code free} is called multiple times, the subsequent
* calls to {@code free} are treated as a no-op.
* If the {@code Blob} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the Blob's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @since 1.6
* @see #close()
*/
void free() throws SQLException;
@ -303,4 +306,23 @@ public interface Blob {
* @since 1.6
*/
InputStream getBinaryStream(long pos, long length) throws SQLException;
/**
* Closes and releases the resources held by this {@code Blob} object.
* <p>
* If the {@code Blob} object is already closed, then invoking this method
* has no effect.
*
* @implSpec The default implementation calls the {@link #free()} method.
*
* @throws SQLException if an error occurs releasing
* the Blob's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @since 26
* @see #free()
*/
default void close() throws SQLException {
free();
};
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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
@ -33,7 +33,7 @@ import java.io.Reader;
* An SQL {@code CLOB} is a built-in type
* that stores a Character Large Object as a column value in a row of
* a database table.
* By default drivers implement a {@code Clob} object using an SQL
* By default, drivers implement a {@code Clob} object using an SQL
* {@code locator(CLOB)}, which means that a {@code Clob} object
* contains a logical pointer to the SQL {@code CLOB} data rather than
* the data itself. A {@code Clob} object is valid for the duration
@ -49,13 +49,19 @@ import java.io.Reader;
* access an SQL {@code CLOB} value. In addition, this interface
* has methods for updating a {@code CLOB} value.
* <p>
* To release resources used by the {@code Clob} object, applications must call
* either the {@link #free()} or the {@link #close()} method. Any attempt to
* invoke a method other than {@link #free()} or {@link #close()} after the
* {@code Clob} object has been closed, will result in a {@link SQLException}
* being thrown.
* <P>
* All methods on the {@code Clob} interface must be
* fully implemented if the JDBC driver supports the data type.
*
* @since 1.2
*/
public interface Clob {
public interface Clob extends AutoCloseable {
/**
* Retrieves the number of characters
@ -310,14 +316,10 @@ public interface Clob {
void truncate(long len) throws SQLException;
/**
* This method releases the resources that the {@code Clob} object
* holds. The object is invalid once the {@code free} method
* is called.
* Closes and releases the resources held by this {@code Clob} object.
* <p>
* After {@code free} has been called, any attempt to invoke a
* method other than {@code free} will result in a {@code SQLException}
* being thrown. If {@code free} is called multiple times, the subsequent
* calls to {@code free} are treated as a no-op.
* If the {@code Clob} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the Clob's resources
@ -325,6 +327,7 @@ public interface Clob {
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @since 1.6
* @see #close()
*/
void free() throws SQLException;
@ -350,4 +353,21 @@ public interface Clob {
*/
Reader getCharacterStream(long pos, long length) throws SQLException;
/**
* Closes and releases the resources held by this {@code Clob} object.
* <p>
* If the {@code Clob} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the Clob's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @implSpec The default implementation calls the {@link #free()} method.
* @see #free()
* @since 26
*/
default void close() throws SQLException {
free();
};
}

View File

@ -43,8 +43,8 @@ import java.util.Map;
* should use the appropriate {@code Connection} method such as
* {@code setAutoCommit} or {@code setTransactionIsolation}.
* Applications should not invoke SQL commands directly to change the connection's
* configuration when there is a JDBC method available. By default a {@code Connection} object is in
* auto-commit mode, which means that it automatically commits changes
* configuration when there is a JDBC method available. By default, a {@code Connection}
* object is in auto-commit mode, which means that it automatically commits changes
* after executing each statement. If auto-commit mode has been
* disabled, the method {@code commit} must be called explicitly in
* order to commit changes; otherwise, database changes will not be saved.
@ -77,7 +77,7 @@ import java.util.Map;
* con.setTypeMap(map);
* </pre>
*
* @see DriverManager#getConnection
* @see DriverManager#getConnection(String)
* @see Statement
* @see ResultSet
* @see DatabaseMetaData
@ -1505,7 +1505,7 @@ public interface Connection extends Wrapper, AutoCloseable {
* </ul>
* @throws SQLException if an error occurs
* @since 9
* @see endRequest
* @see #endRequest()
* @see javax.sql.PooledConnection
*/
default void beginRequest() throws SQLException {
@ -1548,7 +1548,7 @@ public interface Connection extends Wrapper, AutoCloseable {
* </ul>
* @throws SQLException if an error occurs
* @since 9
* @see beginRequest
* @see #beginRequest()
* @see javax.sql.PooledConnection
*/
default void endRequest() throws SQLException {
@ -1676,5 +1676,311 @@ public interface Connection extends Wrapper, AutoCloseable {
default void setShardingKey(ShardingKey shardingKey) throws SQLException {
throw new SQLFeatureNotSupportedException("setShardingKey not implemented");
}
// JDBC 4.5
/**
* Returns a {@code String} enclosed in single quotes. Any occurrence of a
* single quote within the string will be replaced by two single quotes.
*
* <blockquote>
* <table class="striped">
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr><th scope="col">Value</th><th scope="col">Result</th></tr>
* </thead>
* <tbody style="text-align:center">
* <tr> <th scope="row">Hello</th> <td>'Hello'</td> </tr>
* <tr> <th scope="row">G'Day</th> <td>'G''Day'</td> </tr>
* <tr> <th scope="row">'G''Day'</th>
* <td>'''G''''Day'''</td> </tr>
* <tr> <th scope="row">I'''M</th> <td>'I''''''M'</td>
* </tr>
*
* </tbody>
* </table>
* </blockquote>
* @implSpec
* The default implementation creates the literal as:
* {@code "'" + val.replace("'", "''") + "'"}.
* @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 {@code null}
* @throws SQLException if a database access error occurs
*
* @since 26
*/
default String enquoteLiteral(String val) throws SQLException {
return SQLUtils.enquoteLiteral(val);
}
/**
* Returns a {@link #isSimpleIdentifier(String) simple SQL identifier} or a
* delimited identifier. A delimited identifier represents the name of a
* database object such as a table, column, or view that is enclosed by a
* delimiter, which is typically a double quote as defined by the SQL standard.
* <p>
* If {@code identifier} is a simple SQL identifier:
* <ul>
* <li>If {@code alwaysDelimit} is {@code false}, return the original value</li>
* <li>if {@code alwaysDelimit} is {@code true}, enquote the original value
* and return as a delimited identifier</li>
* </ul>
*
* If {@code identifier} is not a simple SQL identifier, the delimited
* {@code identifier} to be returned must be enclosed by the delimiter
* returned from {@link DatabaseMetaData#getIdentifierQuoteString}. If
* the datasource does not support delimited identifiers, a
* {@code SQLFeatureNotSupportedException} is thrown.
* <p>
* A {@code SQLException} will be thrown if {@code identifier} contains any
* invalid characters within 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:
* <ul>
* <li>The string is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a ({@code '\u005C0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters([0-9A-Za-z])
* or the character "_"</li>
* </ul>
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
* <li> {@link DatabaseMetaData#getIdentifierQuoteString} does not return a
* double quote</li>
* <li>{@code identifier} contains a {@code null} character or double quote</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
* <blockquote>
* <table class="striped" >
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">identifier</th>
* <th scope="col">alwaysDelimit</th>
* <th scope="col">Result</th></tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row">Hello</th>
* <td>false</td>
* <td>Hello</td>
* </tr>
* <tr>
* <th scope="row">Hello</th>
* <td>true</td>
* <td>"Hello"</td>
* </tr>
* <tr>
* <th scope="row">G'Day</th>
* <td>false</td>
* <td>"G'Day"</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>false</td>
* <td>"Bruce Wayne"</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>true</td>
* <td>"Bruce Wayne"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>true</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">GoodDay$</th>
* <td>false</td>
* <td>"GoodDay$"</td>
* </tr>
* <tr>
* <th scope="row">Hello"World</th>
* <td>false</td>
* <td>SQLException</td>
* </tr>
* <tr>
* <th scope="row">"Hello"World"</th>
* <td>false</td>
* <td>SQLException</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* @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 alwaysDelimit indicates if a simple SQL identifier should be
* returned as a delimited 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 {@code null}
*
* @since 26
*/
default String enquoteIdentifier(String identifier, boolean alwaysDelimit) throws SQLException {
String delimiter = this.getMetaData().getIdentifierQuoteString();
return SQLUtils.enquoteIdentifier(delimiter, identifier, alwaysDelimit);
}
/**
* Returns whether {@code identifier} is a simple SQL identifier.
* A simple SQL identifier is referred to as regular (or ordinary) identifier
* within the SQL standard. A regular identifier represents the name of a database
* object such as a table, column, or view.
* <p>
* The rules for a regular Identifier are:
* <ul>
* <li>The first character is an alphabetic character from a ({@code '\u005Cu0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters([0-9A-Za-z])
* or the character "_"</li>
* <li>It cannot be a SQL reserved word</li>
* </ul>
* <p>
* A datasource may have additional rules for a regular identifier such as:
* <ul>
* <li>Supports additional characters within the name based on
* the locale being used</li>
* <li>Supports a different maximum length for the identifier</li>
* </ul>
*
* @implSpec The default implementation uses the following criteria to
* determine a valid simple SQL identifier:
* <ul>
* <li>The identifier is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a through z, or
* from A through Z</li>
* <li>The identifier only contains alphanumeric characters([0-9A-Za-z]) or
* the character "_"</li>
* <li>The identifier is not a SQL reserved word</li>
* <li>The identifier is between 1 and 128 characters in length inclusive</li>
* </ul>
*
* <blockquote>
* <table class="striped" >
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">identifier</th>
* <th scope="col">Simple Identifier</th>
* </thead>
*
* <tbody>
* <tr>
* <th scope="row">Hello</th>
* <td>true</td>
* </tr>
* <tr>
* <th scope="row">G'Day</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">GoodDay$</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">Hello"World</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"Hello"World"</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <tr>
* <th scope="row">"from"</th>
* <td>false</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* @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
* @return true if a simple SQL identifier, false otherwise
* @throws NullPointerException if identifier is {@code null}
* @throws SQLException if a database access error occurs
*
* @since 26
*/
default boolean isSimpleIdentifier(String identifier) throws SQLException {
return SQLUtils.isSimpleIdentifier(identifier);
}
/**
* Returns a {@code String} representing a National Character Set Literal
* enclosed in single quotes and prefixed with a upper case letter N.
* Any occurrence of a single quote within the string will be replaced
* by two single quotes.
*
* <blockquote>
* <table class="striped">
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">Value</th>
* <th scope="col">Result</th>
* </tr>
* </thead>
* <tbody>
* <tr> <th scope="row">Hello</th> <td>N'Hello'</td> </tr>
* <tr> <th scope="row">G'Day</th> <td>N'G''Day'</td> </tr>
* <tr> <th scope="row">'G''Day'</th>
* <td>N'''G''''Day'''</td> </tr>
* <tr> <th scope="row">I'''M</th> <td>N'I''''''M'</td>
* <tr> <th scope="row">N'Hello'</th> <td>N'N''Hello'''</td> </tr>
*
* </tbody>
* </table>
* </blockquote>
* @implSpec
* The default implementation creates the literal as:
* {@code "N'" + val.replace("'", "''") + "'"}.
* @implNote
* JDBC driver implementations may need to provide their own implementation
* of this method in order to meet the requirements of the underlying
* datasource. An implementation of enquoteNCharLiteral may accept a different
* set of characters than that accepted by the same drivers implementation of
* enquoteLiteral.
* @param val a character string
* @return the result of replacing every single quote character in the
* argument by two single quote characters where this entire result is
* then prefixed with 'N'.
* @throws NullPointerException if val is {@code null}
* @throws SQLException if a database access error occurs
*
* @since 26
*/
default String enquoteNCharLiteral(String val) throws SQLException {
return SQLUtils.enquoteNCharLiteral(val);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, 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,12 +25,13 @@
package java.sql;
import java.util.Properties;
/**
* <p>Driver properties for making a connection. The
* {@code DriverPropertyInfo} class is of interest only to advanced programmers
* who need to interact with a Driver via the method
* {@code getDriverProperties} to discover
* and supply properties for connections.
* {@code DriverPropertyInfo} class is of interest only to advanced programmers.
* The method {@link Driver#getPropertyInfo(String, Properties)} may be used
* to discover Driver properties.
*
* @since 1.1
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2013, 2025, 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
@ -200,7 +200,21 @@ public enum JDBCType implements SQLType {
/**
* Identifies the generic SQL type {@code TIMESTAMP_WITH_TIMEZONE}.
*/
TIMESTAMP_WITH_TIMEZONE(Types.TIMESTAMP_WITH_TIMEZONE);
TIMESTAMP_WITH_TIMEZONE(Types.TIMESTAMP_WITH_TIMEZONE),
/* JDBC 4.5 Types */
/**
* Identifies the generic SQL type {@code DECFLOAT}.
* @since 26
*/
DECFLOAT(Types.DECFLOAT),
/**
* Identifies the generic SQL type {@code JSON}.
* @since 26
*/
JSON(Types.JSON);
/**
* The Integer value for the JDBCType. It maps to a value in

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2025, 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
@ -31,7 +31,8 @@ package java.sql;
* An SQL {@code NCLOB} is a built-in type
* that stores a Character Large Object using the National Character Set
* as a column value in a row of a database table.
* <P>The {@code NClob} interface extends the {@code Clob} interface
* <P>
* The {@code NClob} interface extends the {@code Clob} interface
* which provides methods for getting the
* length of an SQL {@code NCLOB} value,
* for materializing a {@code NCLOB} value on the client, and for
@ -44,6 +45,12 @@ package java.sql;
* access an SQL {@code NCLOB} value. In addition, this interface
* has methods for updating a {@code NCLOB} value.
* <p>
* To release resources used by the {@code NClob} object, applications must call
* either the {@link #free()} or the {@link #close()} method. Any attempt to
* invoke a method other than {@link #free()} or {@link #close()} after the
* {@code NClob} object has been closed, will result in a {@link SQLException}
* being thrown.
* <P>
* All methods on the {@code NClob} interface must be fully implemented if the
* JDBC driver supports the data type.
*

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2025, 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
@ -29,30 +29,14 @@ package java.sql;
import java.security.*;
/**
* A {@code SQLPermission} object contains
* a name (also referred to as a "target name") but no actions
* list; there is either a named permission or there is not.
* The target name is the name of the permission. The
* naming convention follows the hierarchical property naming convention.
* In addition, an asterisk
* may appear at the end of the name, following a ".", or by itself, to
* signify a wildcard match. For example: {@code loadLibrary.*}
* and {@code *} signify a wildcard match,
* while {@code *loadLibrary} and {@code a*b} do not.
*
* @apiNote
* This permission cannot be used for controlling access to resources
* as the Security Manager is no longer supported.
* This class was only useful in conjunction with the {@link java.lang.SecurityManager},
* which is no longer supported. There is no replacement for this class.
*
* @since 1.3
* @see java.security.BasicPermission
* @see java.security.Permission
* @see java.security.Permissions
* @see java.security.PermissionCollection
* @see java.lang.SecurityManager
*
* @deprecated There is no replacement for this class.
*/
@Deprecated(since="26", forRemoval=true)
public final class SQLPermission extends BasicPermission {
/**

View File

@ -0,0 +1,431 @@
/*
* Copyright (c) 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.sql;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Pattern;
/**
* Utility class used by the Connection & Statement interfaces for their
* shared default methods.
*/
class SQLUtils {
// Pattern used to verify if an identifier is a Simple SQL identifier
private static final Pattern SIMPLE_IDENTIFIER_PATTERN
= Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*");
// Pattern to check if an identifier contains a null character or a double quote
private static final Pattern INVALID_IDENTIFIER_CHARACTERS_PATTERN
= Pattern.compile("[^\u0000\"]+");
// SQL 2023 reserved words
private static final String[] SQL2023_RESERVED_WORDS = {
"ABS", "ABSENT", "ACOS", "ALL", "ALLOCATE", "ALTER", "AND", "ANY",
"ANY_VALUE", "ARE", "ARRAY", "ARRAY_AGG", "ARRAY_MAX_CARDINALITY",
"AS", "ASENSITIVE", "ASIN", "ASYMMETRIC", "AT", "ATAN",
"ATOMIC", "AUTHORIZATION", "AVG",
"BEGIN", "BEGIN_FRAME", "BEGIN_PARTITION", "BETWEEN", "BIGINT",
"BINARY", "BLOB", "BOOLEAN", "BOTH", "BTRIM", "BY",
"CALL", "CALLED", "CARDINALITY", "CASCADED", "CASE", "CAST", "CEIL",
"CEILING", "CHAR", "CHAR_LENGTH",
"CHARACTER", "CHARACTER_LENGTH", "CHECK", "CLASSIFIER", "CLOB",
"CLOSE", "COALESCE", "COLLATE", "COLLECT", "COLUMN", "COMMIT", "CONDITION",
"CONNECT", "CONSTRAINT", "CONTAINS", "CONVERT", "COPY", "CORR", "CORRESPONDING",
"COS", "COSH", "COUNT", "COVAR_POP", "COVAR_SAMP", "CREATE", "CROSS", "CUBE",
"CUME_DIST", "CURRENT",
"CURRENT_CATALOG", "CURRENT_DATE", "CURRENT_DEFAULT_TRANSFORM_GROUP", "CURRENT_PATH",
"CURRENT_ROLE", "CURRENT_SCHEMA", "CURRENT_TIME", "CURRENT_TIMESTAMP",
"CURRENT_TRANSFORM_GROUP_FOR_TYPE", "CURRENT_USER", "CURSOR", "CYCLE",
"DATE", "DAY", "DEALLOCATE", "DEC", "DECFLOAT", "DECIMAL", "DECLARE", "DEFAULT",
"DEFINE", "DELETE", "DENSE_RANK", "DEREF", "DESCRIBE", "DETERMINISTIC",
"DISCONNECT", "DISTINCT", "DOUBLE", "DROP", "DYNAMIC",
"EACH", "ELEMENT", "ELSE", "EMPTY", "END", "END_FRAME", "END_PARTITION",
"END-EXEC", "EQUALS", "ESCAPE", "EVERY", "EXCEPT", "EXEC", "EXECUTE",
"EXISTS", "EXP", "EXTERNAL", "EXTRACT",
"FALSE", "FETCH", "FILTER", "FIRST_VALUE", "FLOAT", "FLOOR", "FOR", "FOREIGN", "FRAME_ROW",
"FREE", "FROM", "FULL", "FUNCTION", "FUSION",
"GET", "GLOBAL", "GRANT", "GREATEST", "GROUP", "GROUPING", "GROUPS",
"HAVING", "HOLD", "HOUR",
"IDENTITY", "IN", "INDICATOR", "INITIAL", "INNER", "INOUT", "INSENSITIVE",
"INSERT", "INT", "INTEGER",
"INTERSECT", "INTERSECTION", "INTERVAL", "INTO", "IS",
"JOIN", "JSON", "JSON_ARRAY", "JSON_ARRAYAGG", "JSON_EXISTS",
"JSON_OBJECT", "JSON_OBJECTAGG", "JSON_QUERY", "JSON_SCALAR",
"JSON_SERIALIZE", "JSON_TABLE", "JSON_TABLE_PRIMITIVE", "JSON_VALUE",
"LAG", "LANGUAGE", "LARGE", " LAST_VALUE", "LATERAL", "LEAD",
"LEADING", "LEAST", "LEFT", "LIKE", "LIKE_REGEX", "LISTAGG",
"LN", "LOCAL", "LOCALTIME", "LOCALTIMESTAMP", "LOG", "LOG10",
"LOWER", "LPAD", "LTRIM",
"MATCH", "MATCH_NUMBER", "MATCH_RECOGNIZE", "MATCHES", "MAX",
"MEMBER", "MERGE", "METHOD", "MIN", "MINUTE", "MOD", "MODIFIES",
"MODULE", "MONTH", "MULTISET",
"NATIONAL", "NATURAL", "NCHAR", "NCLOB", "NEW", "NO", "NONE",
"NORMALIZE", "NOT", "NTH_VALUE", "NTILE", "NULL", "NULLIF", "NUMERIC",
"OCCURRENCES_REGEX", "OCTET_LENGTH", "OF", "OFFSET", "OLD", "OMIT",
"ON", "ONE", "ONLY", "OPEN", "OR", "ORDER", "OUT", "OUTER", "OUTPUT",
"OVER", "OVERLAPS", "OVERLAY",
"PARAMETER", "PARTITION", "PATTERN", "PER", "PERCENT", "PERCENT_RANK",
"PERCENTILE_CONT", "PERCENTILE_DISC", "PERIOD", "PORTION", "POSITION",
"POSITION_REGEX", "POWER", "PRECEDES",
"PRECISION", "PREPARE", "PRIMARY", "PROCEDURE", "PTF",
"RANGE", "RANK", "READS", "REAL", "RECURSIVE", "REF", "REFERENCES",
"REFERENCING", "REGR_AVGX", "REGR_AVGY", "REGR_COUNT", "REGR_INTERCEPT",
"REGR_R2", "REGR_SLOPE", "REGR_SXX", "REGR_SXY", "REGR_SYY",
"RELEASE", "RESULT", "RETURN", "RETURNS", "REVOKE", "RIGHT",
"ROLLBACK", "ROLLUP", "ROW", "ROW_NUMBER", "ROWS", "RPAD", "RTRIM",
"RUNNING",
"SAVEPOINT", "SCOPE", "SCROLL", "SEARCH", "SECOND", "SEEK",
"SELECT", "SENSITIVE", "SESSION_USER", "SET", "SHOW", "SIMILAR",
"SIN", "SINH", "SKIP", "SMALLINT",
"SOME", "SPECIFIC", "SPECIFICTYPE", "SQL", "SQLEXCEPTION", "SQLSTATE",
"SQLWARNING", "SQRT", "START", "STATIC", "STDDEV_POP", "STDDEV_SAMP",
"SUBMULTISET", "SUBSET", "SUBSTRING", "SUBSTRING_REGEX", "SUCCEEDS",
"SUM", "SYMMETRIC", "SYSTEM", "SYSTEM_TIME", "SYSTEM_USER",
"TABLE", "TABLESAMPLE", "TAN", "TANH", "THEN", "TIME", "TIMESTAMP",
"TIMEZONE_HOUR", "TIMEZONE_MINUTE", "TO", "TRAILING", "TRANSLATE",
"TRANSLATE_REGEX", "TRANSLATION", "TREAT", "TRIGGER", "TRIM",
"TRIM_ARRAY", "TRUE", "TRUNCATE",
"UESCAPE", "UNION", "UNIQUE", "UNKNOWN", "UNNEST", "UPDATE", "UPPER",
"USER", "USING",
"VALUE", "VALUES", "VALUE_OF", "VAR_POP", "VAR_SAMP", "VARBINARY",
"VARCHAR", "VARYING", "VERSIONING",
"WHEN", "WHENEVER", "WHERE", "WHILE", "WIDTH_BUCKET", "WINDOW",
"WITH", "WITHIN", "WITHOUT",
"YEAR"
};
private static final Set<String> SQL_RESERVED_WORDS =
new HashSet<>(Arrays.asList(SQL2023_RESERVED_WORDS));
/**
* Returns a {@code String} enclosed in single quotes. Any occurrence of a
* single quote within the string will be replaced by two single quotes.
*
* <blockquote>
* <table class="striped">
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr><th scope="col">Value</th><th scope="col">Result</th></tr>
* </thead>
* <tbody style="text-align:center">
* <tr> <th scope="row">Hello</th> <td>'Hello'</td> </tr>
* <tr> <th scope="row">G'Day</th> <td>'G''Day'</td> </tr>
* <tr> <th scope="row">'G''Day'</th>
* <td>'''G''''Day'''</td> </tr>
* <tr> <th scope="row">I'''M</th> <td>'I''''''M'</td>
* </tr>
*
* </tbody>
* </table>
* </blockquote>
*
* @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 {@code null}
* @throws SQLException if a database access error occurs
* @implNote JDBC driver implementations may need to provide their own implementation
* of this method in order to meet the requirements of the underlying
* datasource.
*/
static String enquoteLiteral(String val) throws SQLException {
return "'" + val.replace("'", "''") + "'";
}
/**
* Returns a {@link #isSimpleIdentifier(String) simple SQL identifier} or a
* delimited identifier. A delimited identifier represents the name of a
* database object such as a table, column, or view that is enclosed by a
* delimiter, which is typically a double quote as defined by the SQL standard.
* <p>
* If {@code identifier} is a simple SQL identifier:
* <ul>
* <li>If {@code alwaysDelimit} is {@code false}, return the original value</li>
* <li>if {@code alwaysDelimit} is {@code true}, enquote the original value
* and return as a delimited identifier</li>
* </ul>
*
* If {@code identifier} is not a simple SQL identifier, the delimited
* {@code identifier} to be returned must be enclosed by the delimiter
* returned from {@link DatabaseMetaData#getIdentifierQuoteString}. If
* the datasource does not support delimited identifiers, a
* {@code SQLFeatureNotSupportedException} is thrown.
* <p>
* A {@code SQLException} will be thrown if {@code identifier} contains any
* invalid characters within 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:
* <ul>
* <li>The string is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a ({@code '\u005C0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters or the character "_"</li>
* </ul>
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
* <li> {@link DatabaseMetaData#getIdentifierQuoteString} does not return a
* double quote</li>
* <li>{@code identifier} contains a {@code null} character or double quote</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
* <blockquote>
* <table class="striped" >
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">identifier</th>
* <th scope="col">alwaysDelimit</th>
* <th scope="col">Result</th></tr>
* </thead>
* <tbody>
* <tr>
* <th scope="row">Hello</th>
* <td>false</td>
* <td>Hello</td>
* </tr>
* <tr>
* <th scope="row">Hello</th>
* <td>true</td>
* <td>"Hello"</td>
* </tr>
* <tr>
* <th scope="row">G'Day</th>
* <td>false</td>
* <td>"G'Day"</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>false</td>
* <td>"Bruce Wayne"</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>true</td>
* <td>"Bruce Wayne"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>true</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">GoodDay$</th>
* <td>false</td>
* <td>"GoodDay$"</td>
* </tr>
* <tr>
* <th scope="row">Hello"World</th>
* <td>false</td>
* <td>SQLException</td>
* </tr>
* <tr>
* <th scope="row">"Hello"World"</th>
* <td>false</td>
* <td>SQLException</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* @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 alwaysDelimit indicates if a simple SQL identifier should be
* returned as a delimited 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 {@code null}
*/
static String enquoteIdentifier(String delimiter, String identifier, boolean alwaysDelimit) throws SQLException {
int len = identifier.length();
if (len < 1 || len > 128) {
throw new SQLException("Invalid identifier length");
}
if (!delimiter.equals("\"")) {
throw new SQLException("Unsupported delimiter");
}
if (isSimpleIdentifier(identifier)) {
return alwaysDelimit ? "\"" + identifier + "\"" : identifier;
}
if (identifier.matches("^\".+\"$")) {
identifier = identifier.substring(1, len - 1);
}
// Enclose the identifier in double quotes. If the identifier
// contains a null character or a double quote, throw a SQLException
if (INVALID_IDENTIFIER_CHARACTERS_PATTERN.matcher(identifier).matches()) {
return "\"" + identifier + "\"";
} else {
throw new SQLException("Invalid name");
}
}
/**
* Returns whether {@code identifier} is a simple SQL identifier.
* A simple SQL identifier is referred to as regular (or ordinary) identifier
* within the SQL standard. A regular identifier represents the name of a database
* object such as a table, column, or view.
* <p>
* The rules for a regular Identifier are:
* <ul>
* <li>The first character is an alphabetic character from a ({@code '\u005Cu0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters or the character "_"</li>
* <li>It cannot be a SQL reserved word</li>
* </ul>
* <p>
* A datasource may have additional rules for a regular identifier such as:
* <ul>
* <li>Supports additional characters within the name based on
* the locale being used</li>
* <li>Supports a different maximum length for the identifier</li>
* </ul>
*
* @implSpec The default implementation uses the following criteria to
* determine a valid simple SQL identifier:
* <ul>
* <li>The identifier is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a through z, or
* from A through Z</li>
* <li>The identifier only contains alphanumeric characters or the character
* "_"</li>
* <li>The identifier is not a SQL reserved word</li>
* <li>The identifier is between 1 and 128 characters in length inclusive</li>
* </ul>
*
* <blockquote>
* <table class="striped" >
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">identifier</th>
* <th scope="col">Simple Identifier</th>
* </thead>
*
* <tbody>
* <tr>
* <th scope="row">Hello</th>
* <td>true</td>
* </tr>
* <tr>
* <th scope="row">G'Day</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"Bruce Wayne"</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">GoodDay$</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">Hello"World</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"Hello"World"</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <tr>
* <th scope="row">"from"</th>
* <td>false</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
* @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
* @return true if a simple SQL identifier, false otherwise
* @throws NullPointerException if identifier is {@code null}
* @throws SQLException if a database access error occurs
*/
static boolean isSimpleIdentifier(String identifier) throws SQLException {
int len = identifier.length();
return !SQL_RESERVED_WORDS.contains(identifier.toUpperCase()) &&
len >= 1 && len <= 128
&& SIMPLE_IDENTIFIER_PATTERN.matcher(identifier).matches();
}
/**
* Returns a {@code String} representing a National Character Set Literal
* enclosed in single quotes and prefixed with an upper case letter N.
* Any occurrence of a single quote within the string will be replaced
* by two single quotes.
*
* <blockquote>
* <table class="striped">
* <caption>Examples of the conversion:</caption>
* <thead>
* <tr>
* <th scope="col">Value</th>
* <th scope="col">Result</th>
* </tr>
* </thead>
* <tbody>
* <tr> <th scope="row">Hello</th> <td>N'Hello'</td> </tr>
* <tr> <th scope="row">G'Day</th> <td>N'G''Day'</td> </tr>
* <tr> <th scope="row">'G''Day'</th>
* <td>N'''G''''Day'''</td> </tr>
* <tr> <th scope="row">I'''M</th> <td>N'I''''''M'</td>
* <tr> <th scope="row">N'Hello'</th> <td>N'N''Hello'''</td> </tr>
*
* </tbody>
* </table>
* </blockquote>
*
* @param val a character string
* @return the result of replacing every single quote character in the
* argument by two single quote characters where this entire result is
* then prefixed with 'N'.
* @throws NullPointerException if val is {@code null}
* @throws SQLException if a database access error occurs
* @implNote JDBC driver implementations may need to provide their own implementation
* of this method in order to meet the requirements of the underlying
* datasource. An implementation of enquoteNCharLiteral may accept a different
* set of characters than that accepted by the same drivers implementation of
* enquoteLiteral.
*/
static String enquoteNCharLiteral(String val) throws SQLException {
return "N'" + val.replace("'", "''") + "'";
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2005, 2025, 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
@ -170,14 +170,19 @@ import javax.xml.transform.Source;
* The conceptual states of writable and not writable determine if one
* of the writing APIs will set a value or throw an exception.
* <p>
* The state moves from readable to not readable once free() or any of the
* The state moves from readable to not readable once close(), free() or any of the
* reading APIs are called: getBinaryStream(), getCharacterStream(), getSource(), and getString().
* Implementations may also change the state to not writable when this occurs.
* <p>
* The state moves from writable to not writable once free() or any of the
* The state moves from writable to not writable once close(), free() or any of the
* writing APIs are called: setBinaryStream(), setCharacterStream(), setResult(), and setString().
* Implementations may also change the state to not readable when this occurs.
*
* <p>
* To release resources used by the {@code SQLXML} object, applications must call
* either the {@link #free()} or the {@link #close()} method. Any attempt to
* invoke a method other than {@link #free()} or {@link #close()} after the
* {@code SQLXML} object has been closed, will result in a {@link SQLException}
* being thrown.
* <p>
* All methods on the {@code SQLXML} interface must be fully implemented if the
* JDBC driver supports the data type.
@ -188,21 +193,19 @@ import javax.xml.transform.Source;
* @see javax.xml.xpath
* @since 1.6
*/
public interface SQLXML
public interface SQLXML extends AutoCloseable
{
/**
* This method closes this object and releases the resources that it held.
* The SQL XML object becomes invalid and neither readable or writable
* when this method is called.
* Closes and releases the resources held by this {@code SQLXML} object.
* <p>
* If the {@code SQLXML} object is already closed, then invoking this method
* has no effect.
*
* After {@code free} has been called, any attempt to invoke a
* method other than {@code free} will result in a {@code SQLException}
* being thrown. If {@code free} is called multiple times, the subsequent
* calls to {@code free} are treated as a no-op.
* @throws SQLException if there is an error freeing the XML value.
* @throws SQLFeatureNotSupportedException if the JDBC driver does not support
* this method
* @since 1.6
* @see #close()
*/
void free() throws SQLException;
@ -424,4 +427,21 @@ public interface SQLXML
*/
<T extends Result> T setResult(Class<T> resultClass) throws SQLException;
/**
* Closes and releases the resources held by this {@code SQLXML} object.
* <p>
* If the {@code SQLXML} object is already closed, then invoking this method
* has no effect.
*
* @throws SQLException if an error occurs releasing
* the SQLXML's resources
* @throws SQLFeatureNotSupportedException if the JDBC driver
* does not support this method
* @implSpec The default implementation calls the {@link #free()} method.
* @see #free()
* @since 26
*/
default void close() throws SQLException {
free();
};
}

View File

@ -25,9 +25,6 @@
package java.sql;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.joining;
/**
* <P>The object used for executing a static SQL statement
* and returning the results it produces.
@ -1395,6 +1392,9 @@ public interface Statement extends Wrapper, AutoCloseable {
* </tbody>
* </table>
* </blockquote>
* @implSpec
* The default implementation creates the literal as:
* {@code "'" + val.replace("'", "''") + "'"}.
* @implNote
* JDBC driver implementations may need to provide their own implementation
* of this method in order to meet the requirements of the underlying
@ -1407,46 +1407,50 @@ public interface Statement extends Wrapper, AutoCloseable {
*
* @since 9
*/
default String enquoteLiteral(String val) throws SQLException {
return "'" + val.replace("'", "''") + "'";
default String enquoteLiteral(String val) throws SQLException {
return SQLUtils.enquoteLiteral(val);
}
/**
* Returns a SQL identifier. If {@code identifier} is a simple SQL identifier:
/**
* Returns a {@link #isSimpleIdentifier(String) simple SQL identifier} or a
* delimited identifier. A delimited identifier represents the name of a
* database object such as a table, column, or view that is enclosed by a
* delimiter, which is typically a double quote as defined by the SQL standard.
* <p>
* If {@code identifier} is a simple SQL identifier:
* <ul>
* <li>Return the original value if {@code alwaysQuote} is
* {@code false}</li>
* <li>Return a delimited identifier if {@code alwaysQuote} is
* {@code true}</li>
* <li>If {@code alwaysDelimit} is {@code false}, return the original value</li>
* <li>if {@code alwaysDelimit} is {@code true}, enquote the original value
* and return as a delimited identifier</li>
* </ul>
*
* 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.
* If {@code identifier} is not a simple SQL identifier, the delimited
* {@code identifier} to be returned must be enclosed by the delimiter
* returned from {@link DatabaseMetaData#getIdentifierQuoteString}. If
* the datasource does not support delimited identifiers, a
* {@code SQLFeatureNotSupportedException} is thrown.
* <p>
* 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.
* invalid characters within 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:
* <ul>
* <li>The string is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a through z, or
* from A through Z</li>
* <li>The name only contains alphanumeric characters or the character "_"</li>
* <li>The first character is an alphabetic character from a ({@code '\u005C0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters([0-9A-Za-z])
* or the character "_"</li>
* </ul>
*
* The default implementation will throw a {@code SQLException} if:
* <ul>
* <li>{@code identifier} contains a {@code null} character or double quote and is not
* a simple SQL identifier.</li>
* <li> {@link DatabaseMetaData#getIdentifierQuoteString} does not return a
* double quote</li>
* <li>{@code identifier} contains a {@code null} character or double quote</li>
* <li>The length of {@code identifier} is less than 1 or greater than 128 characters
* </ul>
* <blockquote>
@ -1455,7 +1459,7 @@ public interface Statement extends Wrapper, AutoCloseable {
* <thead>
* <tr>
* <th scope="col">identifier</th>
* <th scope="col">alwaysQuote</th>
* <th scope="col">alwaysDelimit</th>
* <th scope="col">Result</th></tr>
* </thead>
* <tbody>
@ -1485,6 +1489,16 @@ public interface Statement extends Wrapper, AutoCloseable {
* <td>"Bruce Wayne"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>true</td>
* <td>"select"</td>
* </tr>
* <tr>
* <th scope="row">GoodDay$</th>
* <td>false</td>
* <td>"GoodDay$"</td>
@ -1507,8 +1521,8 @@ public interface Statement extends Wrapper, AutoCloseable {
* 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
* @param alwaysDelimit indicates if a simple SQL identifier should be
* returned as a delimited 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
@ -1517,36 +1531,43 @@ public interface Statement extends Wrapper, AutoCloseable {
*
* @since 9
*/
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");
}
default String enquoteIdentifier(String identifier, boolean alwaysDelimit) throws SQLException {
return getConnection().enquoteIdentifier(identifier,alwaysDelimit);
}
/**
* Retrieves whether {@code identifier} is a simple SQL identifier.
* Returns whether {@code identifier} is a simple SQL identifier.
* A simple SQL identifier is referred to as regular (or ordinary) identifier
* within the SQL standard. A regular identifier represents the name of a database
* object such as a table, column, or view.
* <p>
* The rules for a regular Identifier are:
* <ul>
* <li>The first character is an alphabetic character from a ({@code '\u005Cu0061'})
* through z ({@code '\u005Cu007A'}), or from A ({@code '\u005Cu0041'})
* through Z ({@code '\u005Cu005A'})</li>
* <li>The name only contains alphanumeric characters([0-9A-Za-z]) or the
* character "_"</li>
* <li>It cannot be a SQL reserved word</li>
* </ul>
* <p>
* A datasource may have additional rules for a regular identifier such as:
* <ul>
* <li>Supports additional characters within the name based on
* the locale being used</li>
* <li>Supports a different maximum length for the identifier</li>
* </ul>
*
* @implSpec The default implementation uses the following criteria to
* determine a valid simple SQL identifier:
* <ul>
* <li>The string is not enclosed in double quotes</li>
* <li>The identifier is not enclosed in double quotes</li>
* <li>The first character is an alphabetic character from a through z, or
* from A through Z</li>
* <li>The string only contains alphanumeric characters or the character
* "_"</li>
* <li>The string is between 1 and 128 characters in length inclusive</li>
* <li>The identifier only contains alphanumeric characters([0-9A-Za-z])
* or the character "_"</li>
* <li>The identifier is not a SQL reserved word</li>
* <li>The identifier is between 1 and 128 characters in length inclusive</li>
* </ul>
*
* <blockquote>
@ -1583,6 +1604,13 @@ public interface Statement extends Wrapper, AutoCloseable {
* <th scope="row">"Hello"World"</th>
* <td>false</td>
* </tr>
* <tr>
* <th scope="row">"select"</th>
* <td>false</td>
* <tr>
* <th scope="row">"from"</th>
* <td>false</td>
* </tr>
* </tbody>
* </table>
* </blockquote>
@ -1590,16 +1618,14 @@ public interface Statement extends Wrapper, AutoCloseable {
* implementation of this method in order to meet the requirements of the
* underlying datasource.
* @param identifier a SQL identifier
* @return true if a simple SQL identifier, false otherwise
* @return true if a simple SQL identifier, false otherwise
* @throws NullPointerException if identifier is {@code null}
* @throws SQLException if a database access error occurs
*
* @since 9
*/
default boolean isSimpleIdentifier(String identifier) throws SQLException {
int len = identifier.length();
return len >= 1 && len <= 128
&& Pattern.compile("[\\p{Alpha}][\\p{Alnum}_]*").matcher(identifier).matches();
return SQLUtils.isSimpleIdentifier(identifier);
}
/**
@ -1628,7 +1654,10 @@ public interface Statement extends Wrapper, AutoCloseable {
* </tbody>
* </table>
* </blockquote>
* @implNote
* @implSpec
* The default implementation creates the literal as:
* {@code "N'" + val.replace("'", "''") + "'"}.
* @implNote
* JDBC driver implementations may need to provide their own implementation
* of this method in order to meet the requirements of the underlying
* datasource. An implementation of enquoteNCharLiteral may accept a different
@ -1643,7 +1672,7 @@ public interface Statement extends Wrapper, AutoCloseable {
*
* @since 9
*/
default String enquoteNCharLiteral(String val) throws SQLException {
return "N'" + val.replace("'", "''") + "'";
default String enquoteNCharLiteral(String val) throws SQLException {
return SQLUtils.enquoteNCharLiteral(val);
}
}

View File

@ -54,10 +54,7 @@ import java.time.LocalDateTime;
* because the nanos component of a date is unknown.
* As a result, the {@code Timestamp.equals(Object)}
* method is not symmetric with respect to the
* {@code java.util.Date.equals(Object)}
* method. Also, the {@code hashCode} method uses the underlying
* {@code java.util.Date}
* implementation and therefore does not include nanos in its computation.
* {@code java.util.Date.equals(Object)} method.
* <P>
* Due to the differences between the {@code Timestamp} class
* and the {@code java.util.Date}
@ -465,10 +462,15 @@ public class Timestamp extends java.util.Date {
}
/**
* {@inheritDoc}
* Returns a hash code value for this Timestamp. The result is the
* exclusive OR of the two halves of the primitive {@code long}
* value returned by the {@link #getTime} method. That is,
* the hash code is the value of the expression:
* {@snippet :
* (int)(this.getTime()^(this.getTime() >>> 32))
* }
*
* The {@code hashCode} method uses the underlying {@code java.util.Date}
* implementation and therefore does not include nanos in its computation.
* @return a hash code value for this Timestamp.
*
*/
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1996, 2025, 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
@ -339,6 +339,27 @@ public class Types {
*/
public static final int TIMESTAMP_WITH_TIMEZONE = 2014;
//--------------------------JDBC 4.5 -----------------------------
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* {@code DECFLOAT}.
*
* @since 26
*/
public static final int DECFLOAT = 2015;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* {@code JSON}.
*
* @since 26
*/
public static final int JSON = 2016;
// Prevent instantiation
private Types() {}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2025, 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
@ -38,20 +38,22 @@
* use and update data from a spread sheet, flat file, or any other tabular
* data source.
*
* <h2>What the JDBC 4.3 API Includes</h2>
* The JDBC 4.3 API includes both
* <h2>What the JDBC 4.5 API Includes</h2>
* The JDBC 4.5 API includes both
* the {@code java.sql} package, referred to as the JDBC core API,
* and the {@code javax.sql} package, referred to as the JDBC Optional
* Package API. This complete JDBC API
* is included in the Java Standard Edition (Java SE), version 7.
* is included in the Java Standard Edition (Java SE).
* The {@code javax.sql} package extends the functionality of the JDBC API
* from a client-side API to a server-side API, and it is an essential part
* of the Java Enterprise Edition
* (Java EE) technology.
*
* <h2>Versions</h2>
* The JDBC 4.3 API incorporates all of the previous JDBC API versions:
* The JDBC 4.5 API incorporates all the previous JDBC API versions:
* <UL>
* <LI> The JDBC 4.4 API</li>
* <LI> The JDBC 4.3 API</li>
* <LI> The JDBC 4.2 API</li>
* <LI> The JDBC 4.1 API</li>
* <LI> The JDBC 4.0 API</li>
@ -70,6 +72,10 @@
* Javadoc comments for the JDBC API,
* they indicate the following:
* <UL>
* <LI>Since 26 -- new in the JDBC 4.5 API and part of the Java SE platform,
* version 26</li>
* <LI>Since 24 -- new in the JDBC 4.4 API and part of the Java SE platform,
* version 24</li>
* <LI>Since 9 -- new in the JDBC 4.3 API and part of the Java SE platform,
* version 9</li>
* <LI>Since 1.8 -- new in the JDBC 4.2 API and part of the Java SE platform,
@ -126,6 +132,7 @@
* <LI>{@code Blob} interface -- mapping for SQL {@code BLOB}
* <LI>{@code Clob} interface -- mapping for SQL {@code CLOB}
* <LI>{@code Date} class -- mapping for SQL {@code DATE}
* <LI>{@code JDBCType} class -- provides enum constants for SQL types
* <LI>{@code NClob} interface -- mapping for SQL {@code NCLOB}
* <LI>{@code Ref} interface -- mapping for SQL {@code REF}
* <LI>{@code RowId} interface -- mapping for SQL {@code ROWID}
@ -166,6 +173,26 @@
* </UL>
* </UL>
*
* <h3>{@code java.sql} and {@code javax.sql} Features Introduced in the JDBC 4.5 API</h3>
* <UL>
* <LI>The interfaces {@code Array}, {@code Blob}, {@code Clob}, {@code NClob}
* and {@code SQLXML} now extend the {@code AutoCloseable} interface and
* include a default {@code close} method implementation</LI>
* <LI>Added support to {@code Connection} for enquoting literals
* and simple identifiers</LI>
* <LI> {@code SQLPermissions} has been deprecated for removal</LI>
* <LI> The SQL Types {@code JSON} and {@code DECFLOAT} have been added to
* {@code JDBCType} and {@code Types}</LI>
* </UL>
* <h3>{@code java.sql} and {@code javax.sql} Features Introduced in the JDBC 4.4 API</h3>
* <UL>
* <LI>Remove mention of {@code SecurityManager} and {@code SecurityException}
* as the {@code SecurityManager} is no longer supported</LI>
* <LI> {@code SQLPermissions} can no longer be used to control access to
* resources as the {@code SecurityManager} is no longer supported</LI>
* <LI>Added support to {@code Connection} for enquoting literals
* and simple identifiers</LI>
* </UL>
* <h3>{@code java.sql} and {@code javax.sql} Features Introduced in the JDBC 4.3 API</h3>
* <UL>
* <LI>Added {@code Sharding} support</LI>
@ -232,7 +259,6 @@
*
* </UL>
*
*
* <h3>{@code java.sql} and {@code javax.sql} Features Introduced in the JDBC 3.0 API</h3>
* <UL>
* <LI>Pooled statements -- reuse of statements associated with a pooled
@ -288,7 +314,6 @@
* handling and passing data
* </UL>
*
*
* <h3>Custom Mapping of UDTs</h3>
* A user-defined type (UDT) defined in SQL can be mapped to a class in the Java
* programming language. An SQL structured type or an SQL {@code DISTINCT}
@ -317,7 +342,7 @@
* <h2>Package Specification</h2>
*
* <ul>
* <li><a href="https://jcp.org/en/jsr/detail?id=221">JDBC 4.3 Specification</a>
* <li><a href="https://jcp.org/en/jsr/detail?id=221">JDBC 4.5 Specification</a>
* </ul>
*
* <h2>Related Documentation</h2>
@ -326,7 +351,6 @@
* <li><a href="http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html">
* Lesson:JDBC Basics(The Java Tutorials &gt; JDBC Database Access)</a>
*
* <li>&ldquo;<i>JDBC API Tutorial and Reference, Third Edition</i>&rdquo;
* </ul>
* @since 1.1
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -22,15 +22,108 @@
*/
package test.sql;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import util.StubCallableStatement;
import org.testng.annotations.Test;
import util.BaseTest;
import util.StubConnection;
public class CallableStatementTests extends PreparedStatementTests {
import java.sql.CallableStatement;
import java.sql.SQLException;
import static org.testng.Assert.assertEquals;
public class CallableStatementTests extends BaseTest {
private CallableStatement cstmt;
@BeforeMethod
public void setUpMethod() throws Exception {
stmt = new StubCallableStatement();
cstmt = new StubConnection().prepareCall("{call SuperHero_Proc(?)}");
}
@AfterMethod
public void tearDownMethod() throws Exception {
cstmt.close();
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedLiteralValues")
public void test00(String s, String expected) throws SQLException {
assertEquals(cstmt.enquoteLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test01() throws SQLException {
cstmt.enquoteLiteral(null);
}
/*
* Validate that enquoteIdentifier returns the expected value
*/
@Test(dataProvider = "validIdentifierValues")
public void test02(String s, boolean alwaysQuote, String expected) throws SQLException {
assertEquals(cstmt.enquoteIdentifier(s, alwaysQuote), expected);
}
/*
* Validate that a SQLException is thrown for values that are not valid
* for a SQL identifier
*/
@Test(dataProvider = "invalidIdentifierValues",
expectedExceptions = SQLException.class)
public void test03(String s, boolean alwaysQuote) throws SQLException {
cstmt.enquoteIdentifier(s, alwaysQuote);
}
/*
* Validate a NullPointerException is thrown is the string passed to
* enquoteIdentiifer is null
*/
@Test(dataProvider = "trueFalse",
expectedExceptions = NullPointerException.class)
public void test04(boolean alwaysQuote) throws SQLException {
cstmt.enquoteIdentifier(null, alwaysQuote);
}
/*
* Validate that isSimpleIdentifier returns the expected value
*/
@Test(dataProvider = "simpleIdentifierValues")
public void test05(String s, boolean expected) throws SQLException {
assertEquals(cstmt.isSimpleIdentifier(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* isSimpleIdentifier is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test06() throws SQLException {
cstmt.isSimpleIdentifier(null);
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedNCharLiteralValues")
public void test07(String s, String expected) throws SQLException {
assertEquals(cstmt.enquoteNCharLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteNCharLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test08() throws SQLException {
cstmt.enquoteNCharLiteral(null);
}
}

View File

@ -0,0 +1,123 @@
/*
* Copyright (c) 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package test.sql;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import util.BaseTest;
import util.StubConnection;
import java.sql.SQLException;
import static org.testng.Assert.*;
public class ConnectionTests extends BaseTest {
protected StubConnection conn;
@BeforeMethod
public void setUpMethod() throws Exception {
conn = new StubConnection();
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedLiteralValues")
public void test00(String s, String expected) throws SQLException {
assertEquals(conn.enquoteLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test01() throws SQLException {
conn.enquoteLiteral(null);
}
/*
* Validate that enquoteIdentifier returns the expected value
*/
@Test(dataProvider = "validIdentifierValues")
public void test02(String s, boolean alwaysQuote, String expected) throws SQLException {
assertEquals(conn.enquoteIdentifier(s, alwaysQuote), expected);
}
/*
* Validate that a SQLException is thrown for values that are not valid
* for a SQL identifier
*/
@Test(dataProvider = "invalidIdentifierValues",
expectedExceptions = SQLException.class)
public void test03(String s, boolean alwaysQuote) throws SQLException {
conn.enquoteIdentifier(s, alwaysQuote);
}
/*
* Validate a NullPointerException is thrown is the string passed to
* enquoteIdentiifer is null
*/
@Test(dataProvider = "trueFalse",
expectedExceptions = NullPointerException.class)
public void test04(boolean alwaysQuote) throws SQLException {
conn.enquoteIdentifier(null, alwaysQuote);
}
/*
* Validate that isSimpleIdentifier returns the expected value
*/
@Test(dataProvider = "simpleIdentifierValues")
public void test05(String s, boolean expected) throws SQLException {
assertEquals(conn.isSimpleIdentifier(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* isSimpleIdentifier is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test06() throws SQLException {
conn.isSimpleIdentifier(null);
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedNCharLiteralValues")
public void test07(String s, String expected) throws SQLException {
assertEquals(conn.enquoteNCharLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteNCharLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test08() throws SQLException {
conn.enquoteNCharLiteral(null);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -22,14 +22,109 @@
*/
package test.sql;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import util.StubPreparedStatement;
import org.testng.annotations.Test;
import util.BaseTest;
import util.StubConnection;
public class PreparedStatementTests extends StatementTests {
import java.sql.PreparedStatement;
import java.sql.SQLException;
import static org.testng.Assert.assertEquals;
public class PreparedStatementTests extends BaseTest {
private PreparedStatement pstmt;
@BeforeMethod
public void setUpMethod() throws Exception {
stmt = new StubPreparedStatement();
pstmt = new StubConnection().prepareStatement("Select * from foo were bar = ?");
}
@AfterMethod
public void tearDownMethod() throws Exception {
pstmt.close();
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedLiteralValues")
public void test00(String s, String expected) throws SQLException {
assertEquals(pstmt.enquoteLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test01() throws SQLException {
pstmt.enquoteLiteral(null);
}
/*
* Validate that enquoteIdentifier returns the expected value
*/
@Test(dataProvider = "validIdentifierValues")
public void test02(String s, boolean alwaysQuote, String expected) throws SQLException {
assertEquals(pstmt.enquoteIdentifier(s, alwaysQuote), expected);
}
/*
* Validate that a SQLException is thrown for values that are not valid
* for a SQL identifier
*/
@Test(dataProvider = "invalidIdentifierValues",
expectedExceptions = SQLException.class)
public void test03(String s, boolean alwaysQuote) throws SQLException {
pstmt.enquoteIdentifier(s, alwaysQuote);
}
/*
* Validate a NullPointerException is thrown is the string passed to
* enquoteIdentiifer is null
*/
@Test(dataProvider = "trueFalse",
expectedExceptions = NullPointerException.class)
public void test04(boolean alwaysQuote) throws SQLException {
pstmt.enquoteIdentifier(null, alwaysQuote);
}
/*
* Validate that isSimpleIdentifier returns the expected value
*/
@Test(dataProvider = "simpleIdentifierValues")
public void test05(String s, boolean expected) throws SQLException {
assertEquals(pstmt.isSimpleIdentifier(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* isSimpleIdentifier is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test06() throws SQLException {
pstmt.isSimpleIdentifier(null);
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedNCharLiteralValues")
public void test07(String s, String expected) throws SQLException {
assertEquals(pstmt.enquoteNCharLiteral(s), expected);
}
/*
* Validate a NullPointerException is thrown if the string passed to
* enquoteNCharLiteral is null
*/
@Test(expectedExceptions = NullPointerException.class)
public void test08() throws SQLException {
pstmt.enquoteNCharLiteral(null);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -23,38 +23,31 @@
package test.sql;
import java.sql.SQLException;
import java.sql.Statement;
import static org.testng.Assert.assertEquals;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import org.testng.annotations.*;
import util.BaseTest;
import util.StubStatement;
import util.StubConnection;
public class StatementTests extends BaseTest {
protected StubStatement stmt;
protected static String maxIdentifier;
private Statement stmt;
@BeforeMethod
public void setUpMethod() throws Exception {
stmt = new StubStatement();
stmt = new StubConnection().createStatement();
}
@BeforeClass
public static void setUpClass() throws Exception {
int maxLen = 128;
StringBuilder s = new StringBuilder(maxLen);
for (int i = 0; i < maxLen; i++) {
s.append('a');
}
maxIdentifier = s.toString();
@AfterMethod
public void tearDownMethod() throws Exception {
stmt.close();
}
/*
* Verify that enquoteLiteral creates a valid literal and converts every
* single quote to two single quotes
*/
@Test(dataProvider = "validEnquotedLiteralValues")
public void test00(String s, String expected) throws SQLException {
assertEquals(stmt.enquoteLiteral(s), expected);
@ -67,7 +60,6 @@ public class StatementTests extends BaseTest {
@Test(expectedExceptions = NullPointerException.class)
public void test01() throws SQLException {
stmt.enquoteLiteral(null);
}
/*
@ -76,7 +68,6 @@ public class StatementTests extends BaseTest {
@Test(dataProvider = "validIdentifierValues")
public void test02(String s, boolean alwaysQuote, String expected) throws SQLException {
assertEquals(stmt.enquoteIdentifier(s, alwaysQuote), expected);
}
/*
@ -87,7 +78,6 @@ public class StatementTests extends BaseTest {
expectedExceptions = SQLException.class)
public void test03(String s, boolean alwaysQuote) throws SQLException {
stmt.enquoteIdentifier(s, alwaysQuote);
}
/*
@ -98,7 +88,6 @@ public class StatementTests extends BaseTest {
expectedExceptions = NullPointerException.class)
public void test04(boolean alwaysQuote) throws SQLException {
stmt.enquoteIdentifier(null, alwaysQuote);
}
/*
@ -116,7 +105,6 @@ public class StatementTests extends BaseTest {
@Test(expectedExceptions = NullPointerException.class)
public void test06() throws SQLException {
stmt.isSimpleIdentifier(null);
}
/*
@ -136,97 +124,4 @@ public class StatementTests extends BaseTest {
public void test08() throws SQLException {
stmt.enquoteNCharLiteral(null);
}
/*
* DataProvider used to provide strings that will be used to validate
* that enquoteLiteral converts a string to a literal and every instance of
* a single quote will be converted into two single quotes in the literal.
*/
@DataProvider(name = "validEnquotedLiteralValues")
protected Object[][] validEnquotedLiteralValues() {
return new Object[][]{
{"Hello", "'Hello'"},
{"G'Day", "'G''Day'"},
{"'G''Day'", "'''G''''Day'''"},
{"I'''M", "'I''''''M'"},
{"The Dark Knight", "'The Dark Knight'"}
};
}
/*
* DataProvider used to provide strings that will be used to validate
* that enqouteIdentifier returns a simple SQL Identifier or a double
* quoted identifier
*/
@DataProvider(name = "validIdentifierValues")
protected Object[][] validEnquotedIdentifierValues() {
return new Object[][]{
{"b", false, "b"},
{"b", true, "\"b\""},
{maxIdentifier, false, maxIdentifier},
{maxIdentifier, true, "\"" + maxIdentifier + "\""},
{"Hello", false, "Hello"},
{"Hello", true, "\"Hello\""},
{"G'Day", false, "\"G'Day\""},
{"G'Day", true, "\"G'Day\""},
{"Bruce Wayne", false, "\"Bruce Wayne\""},
{"Bruce Wayne", true, "\"Bruce Wayne\""},
{"GoodDay$", false, "\"GoodDay$\""},
{"GoodDay$", true, "\"GoodDay$\""},};
}
/*
* DataProvider used to provide strings are invalid for enquoteIdentifier
* resulting in a SQLException being thrown
*/
@DataProvider(name = "invalidIdentifierValues")
protected Object[][] invalidEnquotedIdentifierValues() {
return new Object[][]{
{"Hel\"lo", false},
{"\"Hel\"lo\"", true},
{"Hello" + '\0', false},
{"", false},
{maxIdentifier + 'a', false},};
}
/*
* DataProvider used to provide strings that will be used to validate
* that isSimpleIdentifier returns the correct value based on the
* identifier specified.
*/
@DataProvider(name = "simpleIdentifierValues")
protected Object[][] simpleIdentifierValues() {
return new Object[][]{
{"b", true},
{"Hello", true},
{"\"Gotham\"", false},
{"G'Day", false},
{"Bruce Wayne", false},
{"GoodDay$", false},
{"Dick_Grayson", true},
{"Batmobile1966", true},
{maxIdentifier, true},
{maxIdentifier + 'a', false},
{"", false},};
}
/*
* DataProvider used to provide strings that will be used to validate
* that enquoteNCharLiteral converts a string to a National Character
* literal and every instance of
* a single quote will be converted into two single quotes in the literal.
*/
@DataProvider(name = "validEnquotedNCharLiteralValues")
protected Object[][] validEnquotedNCharLiteralValues() {
return new Object[][]{
{"Hello", "N'Hello'"},
{"G'Day", "N'G''Day'"},
{"'G''Day'", "N'''G''''Day'''"},
{"I'''M", "N'I''''''M'"},
{"N'Hello'", "N'N''Hello'''"},
{"The Dark Knight", "N'The Dark Knight'"}
};
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -667,6 +667,44 @@ public class TimestampTests extends BaseTest {
expectThrows(IllegalArgumentException.class, () -> Timestamp.from(Instant.MIN));
}
/*
* Validate that two Timestamp hashCode values are equal when
* the Timestamp values match, including the nanos.
*/
@Test
public void test54() {
long t = System.currentTimeMillis();
Timestamp ts1 = new Timestamp(t);
Timestamp ts2 = new Timestamp(t);
ts1.setNanos(123456789);
ts2.setNanos(123456789);
assertTrue(ts1.equals(ts1));
assertTrue(ts2.equals(ts2));
assertTrue(ts1.equals(ts2));
// As the Timestamp values, including the nanos are the same, the hashCode's
// should be equal
assertEquals(ts1.hashCode(), ts2.hashCode());
}
/*
* Validate that two Timestamp hashCode values are not equal when only
* the nanos value for the Timestamp differ.
*/
@Test
public void test55() {
long t = System.currentTimeMillis();
Timestamp ts1 = new Timestamp(t);
Timestamp ts2 = new Timestamp(t);
// Modify the nanos so that the Timestamp values differ
ts1.setNanos(123456789);
ts2.setNanos(987654321);
assertTrue(ts1.equals(ts1));
assertTrue(ts2.equals(ts2));
assertFalse(ts1.equals(ts2));
// As the nanos differ, the hashCode values should differ
assertNotEquals(ts1.hashCode(), ts2.hashCode());
}
/*
* DataProvider used to provide Timestamps which are not valid and are used
* to validate that an IllegalArgumentException will be thrown from the

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -27,13 +27,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.Policy;
import java.sql.JDBCType;
import java.sql.SQLException;
import org.testng.annotations.AfterClass;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
public class BaseTest {
@ -47,22 +43,7 @@ public class BaseTest {
protected final int errorCode = 21;
protected final String[] msgs = {"Exception 1", "cause 1", "Exception 2",
"Exception 3", "cause 2"};
@BeforeClass
public static void setUpClass() throws Exception {
}
@AfterClass
public static void tearDownClass() throws Exception {
}
@BeforeMethod
public void setUpMethod() throws Exception {
}
@AfterMethod
public void tearDownMethod() throws Exception {
}
private static final String MAX_LENGTH_IDENTIFIER = "a".repeat(128);
/*
* Take some form of SQLException, serialize and deserialize it
@ -92,13 +73,6 @@ public class BaseTest {
return o1;
}
/*
* Utility Method used to set the current Policy
*/
protected static void setPolicy(Policy p) {
Policy.setPolicy(p);
}
/*
* DataProvider used to specify the value to set and check for
* methods using boolean values
@ -123,4 +97,99 @@ public class BaseTest {
}
return o;
}
/*
* DataProvider used to provide strings that will be used to validate
* that enquoteLiteral converts a string to a literal and every instance of
* a single quote will be converted into two single quotes in the literal.
*/
@DataProvider(name = "validEnquotedLiteralValues")
protected Object[][] validEnquotedLiteralValues() {
return new Object[][]{
{"Hello", "'Hello'"},
{"G'Day", "'G''Day'"},
{"'G''Day'", "'''G''''Day'''"},
{"I'''M", "'I''''''M'"},
{"The Dark Knight", "'The Dark Knight'"},
};
}
/*
* DataProvider used to provide strings that will be used to validate
* that enqouteIdentifier returns a simple SQL Identifier or a
* quoted identifier
*/
@DataProvider(name = "validIdentifierValues")
protected Object[][] validEnquotedIdentifierValues() {
return new Object[][]{
{"b", false, "b"},
{"b", true, "\"b\""},
{MAX_LENGTH_IDENTIFIER, false, MAX_LENGTH_IDENTIFIER},
{MAX_LENGTH_IDENTIFIER, true, "\"" + MAX_LENGTH_IDENTIFIER + "\""},
{"Hello", false, "Hello"},
{"Hello", true, "\"Hello\""},
{"G'Day", false, "\"G'Day\""},
{"G'Day", true, "\"G'Day\""},
{"Bruce Wayne", false, "\"Bruce Wayne\""},
{"Bruce Wayne", true, "\"Bruce Wayne\""},
{"select", false, "\"select\""},
{"table", true, "\"table\""},
{"GoodDay$", false, "\"GoodDay$\""},
{"GoodDay$", true, "\"GoodDay$\""},};
}
/*
* DataProvider used to provide strings are invalid for enquoteIdentifier
* resulting in a SQLException being thrown
*/
@DataProvider(name = "invalidIdentifierValues")
protected Object[][] invalidEnquotedIdentifierValues() {
return new Object[][]{
{"Hel\"lo", false},
{"\"Hel\"lo\"", true},
{"Hello" + '\0', false},
{"", false},
{MAX_LENGTH_IDENTIFIER + 'a', false},};
}
/*
* DataProvider used to provide strings that will be used to validate
* that isSimpleIdentifier returns the correct value based on the
* identifier specified.
*/
@DataProvider(name = "simpleIdentifierValues")
protected Object[][] simpleIdentifierValues() {
return new Object[][]{
{"b", true},
{"Hello", true},
{"\"Gotham\"", false},
{"G'Day", false},
{"Bruce Wayne", false},
{"GoodDay$", false},
{"Dick_Grayson", true},
{"Batmobile1966", true},
{MAX_LENGTH_IDENTIFIER, true},
{MAX_LENGTH_IDENTIFIER + 'a', false},
{"", false},
{"select", false}
};
}
/*
* DataProvider used to provide strings that will be used to validate
* that enquoteNCharLiteral converts a string to a National Character
* literal and every instance of
* a single quote will be converted into two single quotes in the literal.
*/
@DataProvider(name = "validEnquotedNCharLiteralValues")
protected Object[][] validEnquotedNCharLiteralValues() {
return new Object[][]{
{"Hello", "N'Hello'"},
{"G'Day", "N'G''Day'"},
{"'G''Day'", "N'''G''''Day'''"},
{"I'''M", "N'I''''''M'"},
{"N'Hello'", "N'N''Hello'''"},
{"The Dark Knight", "N'The Dark Knight'"}
};
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -26,24 +26,17 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.Ref;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.*;
import java.util.Calendar;
import java.util.Map;
public class StubCallableStatement extends StubPreparedStatement
implements CallableStatement{
public StubCallableStatement(StubConnection con) {
super(con);
}
@Override
public void registerOutParameter(int parameterIndex, int sqlType) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
@ -608,5 +601,4 @@ implements CallableStatement{
public <T> T getObject(String parameterName, Class<T> type) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -44,20 +44,25 @@ import java.util.concurrent.Executor;
public class StubConnection implements Connection {
private boolean autoCommit = false;
private boolean isclosed;
public StubConnection() {
isclosed = false;
}
@Override
public Statement createStatement() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return new StubStatement(this);
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return new StubPreparedStatement(this);
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return new StubCallableStatement(this);
}
@Override
@ -89,17 +94,17 @@ public class StubConnection implements Connection {
@Override
public void close() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
isclosed = true;
}
@Override
public boolean isClosed() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return isclosed;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return new StubDatabaseMetaData();
}
@Override

View File

@ -0,0 +1,907 @@
/*
* Copyright (c) 2025, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package util;
import java.sql.*;
public class StubDatabaseMetaData implements DatabaseMetaData {
@Override
public boolean allProceduresAreCallable() throws SQLException {
return false;
}
@Override
public boolean allTablesAreSelectable() throws SQLException {
return false;
}
@Override
public String getURL() throws SQLException {
return "";
}
@Override
public String getUserName() throws SQLException {
return "";
}
@Override
public boolean isReadOnly() throws SQLException {
return false;
}
@Override
public boolean nullsAreSortedHigh() throws SQLException {
return false;
}
@Override
public boolean nullsAreSortedLow() throws SQLException {
return false;
}
@Override
public boolean nullsAreSortedAtStart() throws SQLException {
return false;
}
@Override
public boolean nullsAreSortedAtEnd() throws SQLException {
return false;
}
@Override
public String getDatabaseProductName() throws SQLException {
return "";
}
@Override
public String getDatabaseProductVersion() throws SQLException {
return "";
}
@Override
public String getDriverName() throws SQLException {
return "";
}
@Override
public String getDriverVersion() throws SQLException {
return "";
}
@Override
public int getDriverMajorVersion() {
return 0;
}
@Override
public int getDriverMinorVersion() {
return 0;
}
@Override
public boolean usesLocalFiles() throws SQLException {
return false;
}
@Override
public boolean usesLocalFilePerTable() throws SQLException {
return false;
}
@Override
public boolean supportsMixedCaseIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesUpperCaseIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesLowerCaseIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesMixedCaseIdentifiers() throws SQLException {
return false;
}
@Override
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
return false;
}
@Override
public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
return false;
}
@Override
public String getIdentifierQuoteString() throws SQLException {
return "\"";
}
@Override
public String getSQLKeywords() throws SQLException {
return "";
}
@Override
public String getNumericFunctions() throws SQLException {
return "";
}
@Override
public String getStringFunctions() throws SQLException {
return "";
}
@Override
public String getSystemFunctions() throws SQLException {
return "";
}
@Override
public String getTimeDateFunctions() throws SQLException {
return "";
}
@Override
public String getSearchStringEscape() throws SQLException {
return "";
}
@Override
public String getExtraNameCharacters() throws SQLException {
return "";
}
@Override
public boolean supportsAlterTableWithAddColumn() throws SQLException {
return false;
}
@Override
public boolean supportsAlterTableWithDropColumn() throws SQLException {
return false;
}
@Override
public boolean supportsColumnAliasing() throws SQLException {
return false;
}
@Override
public boolean nullPlusNonNullIsNull() throws SQLException {
return false;
}
@Override
public boolean supportsConvert() throws SQLException {
return false;
}
@Override
public boolean supportsConvert(int fromType, int toType) throws SQLException {
return false;
}
@Override
public boolean supportsTableCorrelationNames() throws SQLException {
return false;
}
@Override
public boolean supportsDifferentTableCorrelationNames() throws SQLException {
return false;
}
@Override
public boolean supportsExpressionsInOrderBy() throws SQLException {
return false;
}
@Override
public boolean supportsOrderByUnrelated() throws SQLException {
return false;
}
@Override
public boolean supportsGroupBy() throws SQLException {
return false;
}
@Override
public boolean supportsGroupByUnrelated() throws SQLException {
return false;
}
@Override
public boolean supportsGroupByBeyondSelect() throws SQLException {
return false;
}
@Override
public boolean supportsLikeEscapeClause() throws SQLException {
return false;
}
@Override
public boolean supportsMultipleResultSets() throws SQLException {
return false;
}
@Override
public boolean supportsMultipleTransactions() throws SQLException {
return false;
}
@Override
public boolean supportsNonNullableColumns() throws SQLException {
return false;
}
@Override
public boolean supportsMinimumSQLGrammar() throws SQLException {
return false;
}
@Override
public boolean supportsCoreSQLGrammar() throws SQLException {
return false;
}
@Override
public boolean supportsExtendedSQLGrammar() throws SQLException {
return false;
}
@Override
public boolean supportsANSI92EntryLevelSQL() throws SQLException {
return false;
}
@Override
public boolean supportsANSI92IntermediateSQL() throws SQLException {
return false;
}
@Override
public boolean supportsANSI92FullSQL() throws SQLException {
return false;
}
@Override
public boolean supportsIntegrityEnhancementFacility() throws SQLException {
return false;
}
@Override
public boolean supportsOuterJoins() throws SQLException {
return false;
}
@Override
public boolean supportsFullOuterJoins() throws SQLException {
return false;
}
@Override
public boolean supportsLimitedOuterJoins() throws SQLException {
return false;
}
@Override
public String getSchemaTerm() throws SQLException {
return "";
}
@Override
public String getProcedureTerm() throws SQLException {
return "";
}
@Override
public String getCatalogTerm() throws SQLException {
return "";
}
@Override
public boolean isCatalogAtStart() throws SQLException {
return false;
}
@Override
public String getCatalogSeparator() throws SQLException {
return "";
}
@Override
public boolean supportsSchemasInDataManipulation() throws SQLException {
return false;
}
@Override
public boolean supportsSchemasInProcedureCalls() throws SQLException {
return false;
}
@Override
public boolean supportsSchemasInTableDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsSchemasInIndexDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsCatalogsInDataManipulation() throws SQLException {
return false;
}
@Override
public boolean supportsCatalogsInProcedureCalls() throws SQLException {
return false;
}
@Override
public boolean supportsCatalogsInTableDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
return false;
}
@Override
public boolean supportsPositionedDelete() throws SQLException {
return false;
}
@Override
public boolean supportsPositionedUpdate() throws SQLException {
return false;
}
@Override
public boolean supportsSelectForUpdate() throws SQLException {
return false;
}
@Override
public boolean supportsStoredProcedures() throws SQLException {
return false;
}
@Override
public boolean supportsSubqueriesInComparisons() throws SQLException {
return false;
}
@Override
public boolean supportsSubqueriesInExists() throws SQLException {
return false;
}
@Override
public boolean supportsSubqueriesInIns() throws SQLException {
return false;
}
@Override
public boolean supportsSubqueriesInQuantifieds() throws SQLException {
return false;
}
@Override
public boolean supportsCorrelatedSubqueries() throws SQLException {
return false;
}
@Override
public boolean supportsUnion() throws SQLException {
return false;
}
@Override
public boolean supportsUnionAll() throws SQLException {
return false;
}
@Override
public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
return false;
}
@Override
public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
return false;
}
@Override
public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
return false;
}
@Override
public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
return false;
}
@Override
public int getMaxBinaryLiteralLength() throws SQLException {
return 0;
}
@Override
public int getMaxCharLiteralLength() throws SQLException {
return 0;
}
@Override
public int getMaxColumnNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxColumnsInGroupBy() throws SQLException {
return 0;
}
@Override
public int getMaxColumnsInIndex() throws SQLException {
return 0;
}
@Override
public int getMaxColumnsInOrderBy() throws SQLException {
return 0;
}
@Override
public int getMaxColumnsInSelect() throws SQLException {
return 0;
}
@Override
public int getMaxColumnsInTable() throws SQLException {
return 0;
}
@Override
public int getMaxConnections() throws SQLException {
return 0;
}
@Override
public int getMaxCursorNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxIndexLength() throws SQLException {
return 0;
}
@Override
public int getMaxSchemaNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxProcedureNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxCatalogNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxRowSize() throws SQLException {
return 0;
}
@Override
public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
return false;
}
@Override
public int getMaxStatementLength() throws SQLException {
return 0;
}
@Override
public int getMaxStatements() throws SQLException {
return 0;
}
@Override
public int getMaxTableNameLength() throws SQLException {
return 0;
}
@Override
public int getMaxTablesInSelect() throws SQLException {
return 0;
}
@Override
public int getMaxUserNameLength() throws SQLException {
return 0;
}
@Override
public int getDefaultTransactionIsolation() throws SQLException {
return 0;
}
@Override
public boolean supportsTransactions() throws SQLException {
return false;
}
@Override
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
return false;
}
@Override
public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
return false;
}
@Override
public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
return false;
}
@Override
public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
return false;
}
@Override
public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
return false;
}
@Override
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
return null;
}
@Override
public ResultSet getSchemas() throws SQLException {
return null;
}
@Override
public ResultSet getCatalogs() throws SQLException {
return null;
}
@Override
public ResultSet getTableTypes() throws SQLException {
return null;
}
@Override
public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException {
return null;
}
@Override
public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
return null;
}
@Override
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
return null;
}
@Override
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
return null;
}
@Override
public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
return null;
}
@Override
public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
return null;
}
@Override
public ResultSet getTypeInfo() throws SQLException {
return null;
}
@Override
public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException {
return null;
}
@Override
public boolean supportsResultSetType(int type) throws SQLException {
return false;
}
@Override
public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
return false;
}
@Override
public boolean ownUpdatesAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean ownDeletesAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean ownInsertsAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean othersUpdatesAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean othersDeletesAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean othersInsertsAreVisible(int type) throws SQLException {
return false;
}
@Override
public boolean updatesAreDetected(int type) throws SQLException {
return false;
}
@Override
public boolean deletesAreDetected(int type) throws SQLException {
return false;
}
@Override
public boolean insertsAreDetected(int type) throws SQLException {
return false;
}
@Override
public boolean supportsBatchUpdates() throws SQLException {
return false;
}
@Override
public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException {
return null;
}
@Override
public Connection getConnection() throws SQLException {
return null;
}
@Override
public boolean supportsSavepoints() throws SQLException {
return false;
}
@Override
public boolean supportsNamedParameters() throws SQLException {
return false;
}
@Override
public boolean supportsMultipleOpenResults() throws SQLException {
return false;
}
@Override
public boolean supportsGetGeneratedKeys() throws SQLException {
return false;
}
@Override
public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException {
return null;
}
@Override
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
return false;
}
@Override
public int getResultSetHoldability() throws SQLException {
return 0;
}
@Override
public int getDatabaseMajorVersion() throws SQLException {
return 0;
}
@Override
public int getDatabaseMinorVersion() throws SQLException {
return 0;
}
@Override
public int getJDBCMajorVersion() throws SQLException {
return 0;
}
@Override
public int getJDBCMinorVersion() throws SQLException {
return 0;
}
@Override
public int getSQLStateType() throws SQLException {
return 0;
}
@Override
public boolean locatorsUpdateCopy() throws SQLException {
return false;
}
@Override
public boolean supportsStatementPooling() throws SQLException {
return false;
}
@Override
public RowIdLifetime getRowIdLifetime() throws SQLException {
return null;
}
@Override
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
return null;
}
@Override
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
return false;
}
@Override
public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
return false;
}
@Override
public ResultSet getClientInfoProperties() throws SQLException {
return null;
}
@Override
public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException {
return null;
}
@Override
public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
return null;
}
@Override
public boolean generatedKeyAlwaysReturned() throws SQLException {
return false;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -26,25 +26,15 @@ import java.io.InputStream;
import java.io.Reader;
import java.math.BigDecimal;
import java.net.URL;
import java.sql.Array;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Date;
import java.sql.NClob;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.Ref;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.RowId;
import java.sql.SQLException;
import java.sql.SQLXML;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.*;
import java.util.Calendar;
public class StubPreparedStatement extends StubStatement implements PreparedStatement{
public StubPreparedStatement(StubConnection con) {
super(con);
}
@Override
public ResultSet executeQuery() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
@ -319,5 +309,4 @@ public class StubPreparedStatement extends StubStatement implements PreparedStat
public void setNClob(int parameterIndex, Reader reader) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2015, 2025, 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
@ -27,11 +27,15 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Statement;
import java.util.regex.Pattern;
import static java.util.stream.Collectors.joining;
public class StubStatement implements Statement {
protected final Connection con;
public StubStatement(StubConnection con) {
this.con = con;
}
@Override
public ResultSet executeQuery(String sql) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
@ -44,7 +48,7 @@ public class StubStatement implements Statement {
@Override
public void close() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
con.close();
}
@Override
@ -169,7 +173,7 @@ public class StubStatement implements Statement {
@Override
public Connection getConnection() throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
return con;
}
@Override
@ -251,7 +255,4 @@ public class StubStatement implements Statement {
public boolean isWrapperFor(Class<?> iface) throws SQLException {
throw new UnsupportedOperationException("Not supported yet.");
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -55,7 +55,6 @@ public class SQLInputImplTests extends BaseTest {
private final String sqlType = "SUPERHERO";
@BeforeMethod
@Override
public void setUpMethod() throws Exception {
map = new HashMap<>();
impl = new TestSQLDataImpl("TestSQLData");
@ -120,7 +119,6 @@ public class SQLInputImplTests extends BaseTest {
SQLInputImpl sqli = new SQLInputImpl(values, map);
Object o = sqli.readObject();
assertTrue(hero.equals(o));
}
/*
@ -204,8 +202,6 @@ public class SQLInputImplTests extends BaseTest {
Object[] values = {struct};
SQLInputImpl sqli = new SQLInputImpl(values, map);
Object o = sqli.readObject();
assertTrue(hero.equals(o));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2025, 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
@ -65,7 +65,6 @@ public class SQLOutputImplTests extends BaseTest {
private SQLOutputImpl outImpl;
@BeforeMethod
@Override
public void setUpMethod() throws Exception {
results = new Vector();
impl = new TestSQLDataImpl("TestSQLData");