提交 11c11898 authored 作者: Thomas Mueller Graf's avatar Thomas Mueller Graf

Formatting and Javadocs

上级 54552660
......@@ -140,7 +140,8 @@ public class Mode {
public boolean onDuplicateKeyUpdate;
/**
* Pattern describing the keys the java.sql.Connection.setClientInfo() method accepts.
* Pattern describing the keys the java.sql.Connection.setClientInfo()
* method accepts.
*/
public Pattern supportedClientInfoPropertiesRegEx;
......@@ -161,9 +162,12 @@ public class Mode {
mode.supportOffsetFetch = true;
mode.sysDummy1 = true;
mode.isolationLevelInSelectOrInsertStatement = true;
// See https://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/com.ibm.db2z11.doc.java/src/tpc/imjcc_r0052001.dita
// See
// https://www.ibm.com/support/knowledgecenter/SSEPEK_11.0.0/
// com.ibm.db2z11.doc.java/src/tpc/imjcc_r0052001.dita
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile("ApplicationName|ClientAccountingInformation|ClientUser|ClientCorrelationToken");
Pattern.compile("ApplicationName|ClientAccountingInformation|" +
"ClientUser|ClientCorrelationToken");
add(mode);
mode = new Mode("Derby");
......@@ -183,7 +187,9 @@ public class Mode {
mode.uniqueIndexSingleNull = true;
mode.allowPlusForStringConcat = true;
// HSQLDB does not support client info properties. See
// http://hsqldb.org/doc/apidocs/org/hsqldb/jdbc/JDBCConnection.html#setClientInfo%28java.lang.String,%20java.lang.String%29
// http://hsqldb.org/doc/apidocs/
// org/hsqldb/jdbc/JDBCConnection.html#
// setClientInfo%28java.lang.String,%20java.lang.String%29
mode.supportedClientInfoPropertiesRegEx = null;
add(mode);
......@@ -205,8 +211,11 @@ public class Mode {
mode.lowerCaseIdentifiers = true;
mode.onDuplicateKeyUpdate = true;
// MySQL allows to use any key for client info entries. See
// http://grepcode.com/file/repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.24/com/mysql/jdbc/JDBC4CommentClientInfoProvider.java
mode.supportedClientInfoPropertiesRegEx = Pattern.compile(".*");
// http://grepcode.com/file/repo1.maven.org/maven2/mysql/
// mysql-connector-java/5.1.24/com/mysql/jdbc/
// JDBC4CommentClientInfoProvider.java
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile(".*");
add(mode);
mode = new Mode("Oracle");
......@@ -217,7 +226,8 @@ public class Mode {
mode.supportPoundSymbolForColumnNames = true;
// Oracle accepts keys of the form <namespace>.*. See
// https://docs.oracle.com/database/121/JJDBC/jdbcvers.htm#JJDBC29006
mode.supportedClientInfoPropertiesRegEx = Pattern.compile(".*\\..*");
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile(".*\\..*");
add(mode);
mode = new Mode("PostgreSQL");
......@@ -228,8 +238,10 @@ public class Mode {
mode.logIsLogBase10 = true;
mode.serialColumnIsNotPK = true;
// PostgreSQL only supports the ApplicationName property. See
// https://github.com/hhru/postgres-jdbc/blob/master/postgresql-jdbc-9.2-1002.src/org/postgresql/jdbc4/AbstractJdbc4Connection.java
mode.supportedClientInfoPropertiesRegEx = Pattern.compile("ApplicationName");
// https://github.com/hhru/postgres-jdbc/blob/master/postgresql-jdbc-9.2-1002.src/
// org/postgresql/jdbc4/AbstractJdbc4Connection.java
mode.supportedClientInfoPropertiesRegEx =
Pattern.compile("ApplicationName");
add(mode);
}
......
......@@ -937,13 +937,13 @@ public class Session extends SessionWithState {
private void cleanTempTables(boolean closeSession) {
if (localTempTables != null && localTempTables.size() > 0) {
synchronized (database) {
Iterator<Table> itr = localTempTables.values().iterator();
while (itr.hasNext()) {
Table table = itr.next();
Iterator<Table> it = localTempTables.values().iterator();
while (it.hasNext()) {
Table table = it.next();
if (closeSession || table.getOnCommitDrop()) {
modificationId++;
table.setModified();
itr.remove();
it.remove();
table.removeChildrenAndResources(this);
if (closeSession) {
// need to commit, otherwise recovery might
......@@ -954,7 +954,8 @@ public class Session extends SessionWithState {
table.truncate(this);
}
}
// sometimes Table#removeChildrenAndResources will take the meta lock
// sometimes Table#removeChildrenAndResources
// will take the meta lock
if (closeSession) {
database.unlockMeta(this);
}
......
......@@ -288,12 +288,18 @@ public class ExpressionVisitor {
return type;
}
/**
* Get the set of columns of all tables.
*
* @param filters the filters
* @return the set of columns
*/
public static HashSet<Column> allColumnsForTableFilters(TableFilter[] filters) {
HashSet<Column> allColumnsSet = New.hashSet();
for (int i = 0; i < filters.length; i++) {
if (filters[i].getSelect() != null) {
filters[i].getSelect().isEverything(ExpressionVisitor.getColumnsVisitor(allColumnsSet));
filters[i].getSelect().isEverything(
ExpressionVisitor.getColumnsVisitor(allColumnsSet));
}
}
return allColumnsSet;
......
......@@ -156,6 +156,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
* @param filter the current table filter index
* @param sortOrder the sort order
* @param isScanIndex whether this is a "table scan" index
* @param allColumnsSet the set of all columns
* @return the estimated cost
*/
protected final long getCostRangeIndex(int[] masks, long rowCount,
......@@ -240,8 +241,8 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
}
}
// If we have two indexes with the same cost, and one of the indexes can
// satisfy the query without needing to read from the primary table (scan index),
// make that one slightly lower cost.
// satisfy the query without needing to read from the primary table
// (scan index), make that one slightly lower cost.
boolean needsToReadFromScanIndex = true;
if (!isScanIndex && allColumnsSet != null && !allColumnsSet.isEmpty()) {
boolean foundAllColumnsWeNeed = true;
......
......@@ -85,6 +85,7 @@ public interface Index extends SchemaObject {
* @param filters all joined table filters
* @param filter the current table filter index
* @param sortOrder the sort order
* @param allColumnsSet the set of all columns
* @return the estimated cost
*/
double getCost(Session session, int[] masks, TableFilter[] filters, int filter,
......
......@@ -20,10 +20,13 @@ public interface SpatialIndex extends Index {
*
* @param filter the table filter (which possibly knows about additional
* conditions)
* @param first the lower bound
* @param last the upper bound
* @param intersection the geometry which values should intersect with, or
* null for anything
* @return the cursor to iterate over the results
*/
Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last, SearchRow intersection);
Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last,
SearchRow intersection);
}
......@@ -168,7 +168,8 @@ public class SpatialTreeIndex extends BaseIndex implements SpatialIndex {
}
@Override
public Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last, SearchRow intersection) {
public Cursor findByGeometry(TableFilter filter, SearchRow first,
SearchRow last, SearchRow intersection) {
if (intersection == null) {
return find(filter.getSession(), first, last);
}
......
......@@ -160,7 +160,8 @@ public class ViewIndex extends BaseIndex implements SpatialIndex {
}
@Override
public Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last, SearchRow intersection) {
public Cursor findByGeometry(TableFilter filter, SearchRow first,
SearchRow last, SearchRow intersection) {
return find(filter.getSession(), first, last, intersection);
}
......
......@@ -1675,16 +1675,21 @@ public class JdbcConnection extends TraceObject implements Connection {
}
/**
* Set a client property.
* This method always throws a SQLClientInfoException in standard mode.
* In compatibility mode the following properties are supported:
* <p><ul>
* <li>DB2: The properties: ApplicationName, ClientAccountingInformation, ClientUser and ClientCorrelationToken
* are supported.
* Set a client property. This method always throws a SQLClientInfoException
* in standard mode. In compatibility mode the following properties are
* supported:
* <ul>
* <li>DB2: The properties: ApplicationName, ClientAccountingInformation,
* ClientUser and ClientCorrelationToken are supported.
* </li>
* <li>MySQL: All property names are supported.
* <li>Oracle: All properties in the form <namespace>.<key name> are supported.
* </li>
* <li>Oracle: All properties in the form &lt;namespace&gt;.&lt;key name&gt;
* are supported.
* </li>
* <li>PostgreSQL: The ApplicationName property is supported.
* </ul><p>
* </li>
* </ul>
*
* For unsupported properties a SQLClientInfoException is thrown.
*
......@@ -1703,11 +1708,13 @@ public class JdbcConnection extends TraceObject implements Connection {
checkClosed();
if (isInternalProperty(name)) {
throw new SQLClientInfoException("Property name '" + name + " is used internally by H2.",
Collections.<String, ClientInfoStatus> emptyMap());
throw new SQLClientInfoException("Property name '" + name +
" is used internally by H2.",
Collections.<String, ClientInfoStatus> emptyMap());
}
Pattern clientInfoNameRegEx = Mode.getInstance(getMode()).supportedClientInfoPropertiesRegEx;
Pattern clientInfoNameRegEx =
Mode.getInstance(getMode()).supportedClientInfoPropertiesRegEx;
if (clientInfoNameRegEx != null && clientInfoNameRegEx.matcher(name).matches()) {
if (clientInfo == null) {
......@@ -1739,8 +1746,9 @@ public class JdbcConnection extends TraceObject implements Connection {
/**
* Set the client properties. This replaces all existing properties.
*
* This method always throws a SQLClientInfoException in standard mode. In compatibility mode
* some properties may be supported (see setProperty(String, String) for details).
* This method always throws a SQLClientInfoException in standard mode. In
* compatibility mode some properties may be supported (see
* setProperty(String, String) for details).
*
* @param properties the properties (ignored)
*/
......@@ -1801,7 +1809,8 @@ public class JdbcConnection extends TraceObject implements Connection {
* Get a client property.
*
* @param name the client info name
* @return the property value or null if the property is not found or not supported.
* @return the property value or null if the property is not found or not
* supported.
*/
@Override
public String getClientInfo(String name) throws SQLException {
......
......@@ -197,7 +197,8 @@ public class MVSpatialIndex extends BaseIndex implements SpatialIndex, MVIndex {
}
@Override
public Cursor findByGeometry(TableFilter filter, SearchRow first, SearchRow last, SearchRow intersection) {
public Cursor findByGeometry(TableFilter filter, SearchRow first,
SearchRow last, SearchRow intersection) {
Session session = filter.getSession();
if (intersection == null) {
return find(session, first, last);
......
......@@ -52,18 +52,20 @@ public class CipherFactory {
*/
public static final String KEYSTORE_PASSWORD =
"h2pass";
/**
* The security property which can prevent anonymous TLS connections.
* Introduced into Java 6,7,8 in updates from July 2015.
* Introduced into Java 6, 7, 8 in updates from July 2015.
*/
public static final String LEGACY_ALGORITHMS_SECURITY_KEY =
"jdk.tls.legacyAlgorithms";
/**
* The value of {@value #LEGACY_ALGORITHMS_SECURITY_KEY} security
* property at the time of class initialization.
* Null if it is not set.
*/
public static final String DEFAULT_LEGACY_ALGORITHMS = getLegacyAlgoritmsSilently();
public static final String DEFAULT_LEGACY_ALGORITHMS = getLegacyAlgorithmsSilently();
private static final String KEYSTORE =
"~/.h2.keystore";
......@@ -201,7 +203,7 @@ public class CipherFactory {
* behavior.
*/
public static synchronized void removeAnonFromLegacyAlgorithms() {
String legacyAlgosOrig = getLegacyAlgoritmsSilently();
String legacyAlgosOrig = getLegacyAlgorithmsSilently();
if (legacyAlgosOrig == null) {
return;
}
......@@ -227,10 +229,11 @@ public class CipherFactory {
/**
* Returns the security property {@value #LEGACY_ALGORITHMS_SECURITY_KEY}.
* Ignores security exceptions.
*
* @return the value of the security property, or null if not set
* or not accessible
*/
public static String getLegacyAlgoritmsSilently() {
public static String getLegacyAlgorithmsSilently() {
String defaultLegacyAlgorithms = null;
try {
defaultLegacyAlgorithms = Security.getProperty(LEGACY_ALGORITHMS_SECURITY_KEY);
......
......@@ -298,7 +298,8 @@ public class Column {
} else if (dt.type == Value.TIMESTAMP_UTC) {
value = ValueTimestampUtc.fromMillis(session.getTransactionStart());
} else if (dt.type == Value.TIMESTAMP_TZ) {
value = ValueTimestampTimeZone.fromMillis(session.getTransactionStart(), (short) 0);
value = ValueTimestampTimeZone.fromMillis(
session.getTransactionStart(), (short) 0);
} else if (dt.type == Value.TIME) {
value = ValueTime.fromNanos(0);
} else if (dt.type == Value.DATE) {
......
......@@ -113,7 +113,8 @@ public class Plan {
}
double cost = 1;
boolean invalidPlan = false;
final HashSet<Column> allColumnsSet = ExpressionVisitor.allColumnsForTableFilters(allFilters);
final HashSet<Column> allColumnsSet = ExpressionVisitor
.allColumnsForTableFilters(allFilters);
for (int i = 0; i < allFilters.length; i++) {
TableFilter tableFilter = allFilters[i];
if (t.isDebugEnabled()) {
......
......@@ -703,6 +703,7 @@ public abstract class Table extends SchemaObjectBase {
* @param filters all joined table filters
* @param filter the current table filter index
* @param sortOrder the sort order
* @param allColumnsSet the set of all columns
* @return the plan item
*/
public PlanItem getBestPlanItem(Session session, int[] masks,
......@@ -720,7 +721,8 @@ public abstract class Table extends SchemaObjectBase {
if (indexes != null && masks != null) {
for (int i = 1, size = indexes.size(); i < size; i++) {
Index index = indexes.get(i);
double cost = index.getCost(session, masks, filters, filter, sortOrder, allColumnsSet);
double cost = index.getCost(session, masks, filters, filter,
sortOrder, allColumnsSet);
if (t.isDebugEnabled()) {
t.debug("Table : potential plan item cost {0} index {1}",
cost, index.getPlanSQL());
......
......@@ -184,6 +184,7 @@ public class TableFilter implements ColumnResolver {
* @param s the session
* @param filters all joined table filters
* @param filter the current table filter index
* @param allColumnsSet the set of all columns
* @return the best plan item
*/
public PlanItem getBestPlanItem(Session s, TableFilter[] filters, int filter,
......@@ -195,8 +196,10 @@ public class TableFilter implements ColumnResolver {
}
if (indexConditions.size() == 0) {
item1 = new PlanItem();
item1.setIndex(table.getScanIndex(s, null, filters, filter, sortOrder, allColumnsSet));
item1.cost = item1.getIndex().getCost(s, null, filters, filter, sortOrder, allColumnsSet);
item1.setIndex(table.getScanIndex(s, null, filters, filter,
sortOrder, allColumnsSet));
item1.cost = item1.getIndex().getCost(s, null, filters, filter,
sortOrder, allColumnsSet);
}
int len = table.getColumns().length;
int[] masks = new int[len];
......
......@@ -557,6 +557,12 @@ public class TableView extends Table {
return 0;
}
/**
* Get the index of the first parameter.
*
* @param additionalParameters additional parameters
* @return the index of the first parameter
*/
public int getParameterOffset(ArrayList<Parameter> additionalParameters) {
int result = topQuery == null ? -1 : getMaxParameterIndex(topQuery.getParameters());
if (additionalParameters != null) {
......
......@@ -314,7 +314,8 @@ public class DateTimeUtils {
}
/**
* Parse a time string. The format is: [-]hour:minute:second[.nanos] or alternatively [-]hour.minute.second[.nanos].
* Parse a time string. The format is: [-]hour:minute:second[.nanos] or
* alternatively [-]hour.minute.second[.nanos].
*
* @param s the string to parse
* @param start the parse index start
......@@ -332,7 +333,8 @@ public class DateTimeUtils {
int s2 = s.indexOf(':', s1 + 1);
int s3 = s.indexOf('.', s2 + 1);
if (s1 <= 0 || s2 <= s1) {
// if first try fails try to use IBM DB2 time format [-]hour.minute.second[.nanos]
// if first try fails try to use IBM DB2 time format
// [-]hour.minute.second[.nanos]
s1 = s.indexOf('.', start);
s2 = s.indexOf('.', s1 + 1);
s3 = s.indexOf('.', s2 + 1);
......
......@@ -589,7 +589,8 @@ public class Transfer {
return ValueTimestampUtc.fromNanos(readLong());
}
case Value.TIMESTAMP_TZ: {
return ValueTimestampTimeZone.fromDateValueAndNanos(readLong(), readLong(), (short) readInt());
return ValueTimestampTimeZone.fromDateValueAndNanos(readLong(),
readLong(), (short) readInt());
}
case Value.DECIMAL:
return ValueDecimal.get(new BigDecimal(readString()));
......
......@@ -20,7 +20,8 @@ import org.h2.util.StringUtils;
/**
* Implementation of the TIMESTAMP WITH TIMEZONE data type.
*
* @see <a href="https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators">ISO 8601 Time zone designators</a>
* @see <a href="https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators">
* ISO 8601 Time zone designators</a>
*/
public class ValueTimestampTimeZone extends Value {
......@@ -54,12 +55,15 @@ public class ValueTimestampTimeZone extends Value {
*/
private final short timeZoneOffsetMins;
private ValueTimestampTimeZone(long dateValue, long timeNanos, short timeZoneOffsetMins) {
private ValueTimestampTimeZone(long dateValue, long timeNanos,
short timeZoneOffsetMins) {
if (timeNanos < 0 || timeNanos >= 24L * 60 * 60 * 1000 * 1000 * 1000) {
throw new IllegalArgumentException("timeNanos out of range " + timeNanos);
throw new IllegalArgumentException("timeNanos out of range " +
timeNanos);
}
if (timeZoneOffsetMins < (-12 * 60) || timeZoneOffsetMins >= (12 * 60)) {
throw new IllegalArgumentException("timeZoneOffsetMins out of range " + timeZoneOffsetMins);
throw new IllegalArgumentException(
"timeZoneOffsetMins out of range " + timeZoneOffsetMins);
}
this.dateValue = dateValue;
this.timeNanos = timeNanos;
......@@ -72,10 +76,13 @@ public class ValueTimestampTimeZone extends Value {
* @param dateValue the date value, a bit field with bits for the year,
* month, and day
* @param timeNanos the nanoseconds since midnight
* @param timeZoneOffsetMins the timezone offset in minutes
* @return the value
*/
public static ValueTimestampTimeZone fromDateValueAndNanos(long dateValue, long timeNanos, short timeZoneOffsetMins) {
return (ValueTimestampTimeZone) Value.cache(new ValueTimestampTimeZone(dateValue, timeNanos, timeZoneOffsetMins));
public static ValueTimestampTimeZone fromDateValueAndNanos(long dateValue,
long timeNanos, short timeZoneOffsetMins) {
return (ValueTimestampTimeZone) Value.cache(new ValueTimestampTimeZone(
dateValue, timeNanos, timeZoneOffsetMins));
}
/**
......@@ -89,7 +96,8 @@ public class ValueTimestampTimeZone extends Value {
long nanos = timestamp.getNanos() % 1000000;
long dateValue = DateTimeUtils.dateValueFromDate(ms);
nanos += DateTimeUtils.nanosFromDate(ms);
return fromDateValueAndNanos(dateValue, nanos, timestamp.getTimeZoneOffsetMins());
return fromDateValueAndNanos(dateValue, nanos,
timestamp.getTimeZoneOffsetMins());
}
/**
......@@ -97,9 +105,11 @@ public class ValueTimestampTimeZone extends Value {
*
* @param ms the milliseconds
* @param nanos the nanoseconds
* @param timeZoneOffsetMins the timezone offset in minutes
* @return the value
*/
public static ValueTimestampTimeZone fromMillisNanos(long ms, int nanos, short timeZoneOffsetMins) {
public static ValueTimestampTimeZone fromMillisNanos(long ms, int nanos,
short timeZoneOffsetMins) {
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long timeNanos = nanos + DateTimeUtils.nanosFromDate(ms);
return fromDateValueAndNanos(dateValue, timeNanos, timeZoneOffsetMins);
......@@ -109,9 +119,11 @@ public class ValueTimestampTimeZone extends Value {
* Get or create a timestamp value for the given date/time in millis.
*
* @param ms the milliseconds
* @param timeZoneOffsetMins the timezone offset in minutes
* @return the value
*/
public static ValueTimestampTimeZone fromMillis(long ms, short timeZoneOffsetMins) {
public static ValueTimestampTimeZone fromMillis(long ms,
short timeZoneOffsetMins) {
long dateValue = DateTimeUtils.dateValueFromDate(ms);
long nanos = DateTimeUtils.nanosFromDate(ms);
return fromDateValueAndNanos(dateValue, nanos, timeZoneOffsetMins);
......@@ -188,7 +200,8 @@ public class ValueTimestampTimeZone extends Value {
}
nanos = DateTimeUtils.parseTimeNanos(s, dateEnd + 1, timeEnd, true);
}
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tzMinutes);
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos,
tzMinutes);
}
/**
......@@ -221,8 +234,10 @@ public class ValueTimestampTimeZone extends Value {
@Override
public Timestamp getTimestamp() {
Timestamp ts = DateTimeUtils.convertDateValueToTimestamp(dateValue, timeNanos);
return new TimestampWithTimeZone(ts.getTime(), ts.getNanos(), getTimeZoneOffsetMins());
Timestamp ts = DateTimeUtils.convertDateValueToTimestamp(dateValue,
timeNanos);
return new TimestampWithTimeZone(ts.getTime(), ts.getNanos(),
getTimeZoneOffsetMins());
}
@Override
......@@ -324,12 +339,14 @@ public class ValueTimestampTimeZone extends Value {
return false;
}
ValueTimestampTimeZone x = (ValueTimestampTimeZone) other;
return dateValue == x.dateValue && timeNanos == x.timeNanos && timeZoneOffsetMins == x.timeZoneOffsetMins;
return dateValue == x.dateValue && timeNanos == x.timeNanos &&
timeZoneOffsetMins == x.timeZoneOffsetMins;
}
@Override
public int hashCode() {
return (int) (dateValue ^ (dateValue >>> 32) ^ timeNanos ^ (timeNanos >>> 32) ^ timeZoneOffsetMins);
return (int) (dateValue ^ (dateValue >>> 32) ^ timeNanos ^
(timeNanos >>> 32) ^ timeZoneOffsetMins);
}
@Override
......@@ -345,12 +362,16 @@ public class ValueTimestampTimeZone extends Value {
@Override
public Value add(Value v) {
throw DbException.getUnsupportedException("manipulating TIMESTAMP WITH TIMEZONE values is unsupported");
throw DbException
.getUnsupportedException(
"manipulating TIMESTAMP WITH TIMEZONE values is unsupported");
}
@Override
public Value subtract(Value v) {
throw DbException.getUnsupportedException("manipulating TIMESTAMP WITH TIMEZONE values is unsupported");
throw DbException
.getUnsupportedException(
"manipulating TIMESTAMP WITH TIMEZONE values is unsupported");
}
}
......@@ -147,18 +147,24 @@ public class TestCompatibilityOracle extends TestBase {
Connection conn = getConnection("oracle;MODE=Oracle");
Statement stat = conn.createStatement();
stat.execute("CREATE TABLE DATETABLE (ID NUMBER PRIMARY KEY, TESTVAL TIMESTAMP)");
stat.execute("INSERT INTO DATETABLE VALUES (1, to_date('31-DEC-9999 23:59:59','DD-MON-RRRR HH24:MI:SS'))");
stat.execute("INSERT INTO DATETABLE VALUES (2, to_date('01-JAN-0001 00:00:00','DD-MON-RRRR HH24:MI:SS'))");
stat.execute("CREATE TABLE DATE_TABLE (ID NUMBER PRIMARY KEY, TEST_VAL TIMESTAMP)");
stat.execute("INSERT INTO DATE_TABLE VALUES (1, " +
"to_date('31-DEC-9999 23:59:59','DD-MON-RRRR HH24:MI:SS'))");
stat.execute("INSERT INTO DATE_TABLE VALUES (2, " +
"to_date('01-JAN-0001 00:00:00','DD-MON-RRRR HH24:MI:SS'))");
assertResultDate("9999-12-31T23:59:59", stat, "SELECT TESTVAL FROM DATETABLE WHERE ID=1");
assertResultDate("0001-01-01T00:00:00", stat, "SELECT TESTVAL FROM DATETABLE WHERE ID=2");
assertResultDate("9999-12-31T23:59:59", stat,
"SELECT TEST_VAL FROM DATE_TABLE WHERE ID=1");
assertResultDate("0001-01-01T00:00:00", stat,
"SELECT TEST_VAL FROM DATE_TABLE WHERE ID=2");
conn.close();
}
private void assertResultDate(String expected, Statement stat, String sql) throws SQLException {
SimpleDateFormat iso8601 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
private void assertResultDate(String expected, Statement stat, String sql)
throws SQLException {
SimpleDateFormat iso8601 = new SimpleDateFormat(
"yyyy-MM-dd'T'HH:mm:ss");
ResultSet rs = stat.executeQuery(sql);
if (rs.next()) {
assertEquals(expected, iso8601.format(rs.getTimestamp(1)));
......
......@@ -1407,10 +1407,12 @@ public class TestFunctions extends TestBase implements AggregateFunction {
date = new SimpleDateFormat("yyyy-MM-dd").parse("2013-01-29");
assertEquals(date, ToDateParser.toDate("113029", "J"));
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").parse("9999-12-31T23:59:59");
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59","DD-MON-YYYY HH24:MI:SS"));
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59","DD-MON-RRRR HH24:MI:SS"));
date = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
.parse("9999-12-31T23:59:59");
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59",
"DD-MON-YYYY HH24:MI:SS"));
assertEquals(date, ToDateParser.toDate("31-DEC-9999 23:59:59",
"DD-MON-RRRR HH24:MI:SS"));
SimpleDateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
assertEquals(ymd.parse("0001-03-01"), ToDateParser.toDate("1-MAR-0001", "DD-MON-RRRR"));
......@@ -1661,7 +1663,8 @@ public class TestFunctions extends TestBase implements AggregateFunction {
}
private void testIfNull() throws SQLException {
Connection conn = getConnection("functions");
Statement stat = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
Statement stat = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
stat.execute("CREATE TABLE T(f1 double)");
stat.executeUpdate("INSERT INTO T VALUES( 1.2 )");
stat.executeUpdate("INSERT INTO T VALUES( null )");
......
......@@ -148,7 +148,8 @@ public class TestRecursiveQueries extends TestBase {
null, null);
rs = stat.executeQuery("select x from system_range(1,5) "
+ "where x not in (with w(x) as (select 1 union all select x+1 from w where x<3) select x from w)");
+ "where x not in (with w(x) as (select 1 union all select x+1 from w where x<3) "
+ "select x from w)");
assertResultSetOrdered(rs, new String[][]{{"4"}, {"5"}});
conn.close();
......
......@@ -1512,9 +1512,11 @@ public class TestTableEngines extends TestBase {
@Override
public double getCost(Session session, int[] masks,
TableFilter[] filters, int filter, SortOrder sortOrder, HashSet<Column> allColumnsSet) {
TableFilter[] filters, int filter, SortOrder sortOrder,
HashSet<Column> allColumnsSet) {
doTests(session);
return getCostRangeIndex(masks, set.size(), filters, filter, sortOrder, false, allColumnsSet);
return getCostRangeIndex(masks, set.size(), filters, filter,
sortOrder, false, allColumnsSet);
}
@Override
......
......@@ -57,7 +57,7 @@ public class BuildBase {
@Target(ElementType.METHOD)
@Documented
public static @interface Description {
String summary() default "";
String summary() default "";
}
/**
......@@ -317,7 +317,8 @@ public class BuildBase {
if (!Modifier.isStatic(mod) && Modifier.isPublic(mod)
&& m.getParameterTypes().length == 0) {
if (m.isAnnotationPresent(Description.class)) {
description = String.format("%1$-20s %2$s", m.getName(), m.getAnnotation(Description.class).summary());
description = String.format("%1$-20s %2$s",
m.getName(), m.getAnnotation(Description.class).summary());
} else {
description = m.getName();
}
......@@ -355,7 +356,8 @@ public class BuildBase {
}
/**
* Execute java in a separate process, but using the java executable of the current JRE.
* Execute java in a separate process, but using the java executable of the
* current JRE.
*
* @param args the command line parameters for the java command
* @return the exit value
......
......@@ -538,10 +538,13 @@ public class ArchiveTool {
long inPos = 0;
int bufferTotal = 64 * 1024 * 1024;
int bufferPerStream = bufferTotal / segmentStart.size();
// FileChannel fc = new RandomAccessFile(tempFileName, "r").getChannel();
// FileChannel fc = new RandomAccessFile(tempFileName, "r").
// getChannel();
for (int i = 0; i < segmentStart.size(); i++) {
// long end = i < segmentStart.size() - 1 ? segmentStart.get(i+1) : fc.size();
// InputStream in = new SharedInputStream(fc, segmentStart.get(i), end);
// long end = i < segmentStart.size() - 1 ?
// segmentStart.get(i+1) : fc.size();
// InputStream in =
// new SharedInputStream(fc, segmentStart.get(i), end);
InputStream in = new FileInputStream(tempFileName);
in.skip(segmentStart.get(i));
ChunkStream s = new ChunkStream(i);
......@@ -1062,6 +1065,9 @@ public class ArchiveTool {
return x;
}
/**
* An input stream that uses a shared file channel.
*/
static class SharedInputStream extends InputStream {
private final FileChannel channel;
private final long endPosition;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论