提交 566f4756 authored 作者: lukaseder's avatar lukaseder

Merge remote-tracking branch 'upstream/master'

# Conflicts:
#	h2/src/main/org/h2/res/help.csv
......@@ -31,7 +31,7 @@ Change Log
</li>
<li>Issue #249: Clarify license declaration in Maven POM xml
</li>
<li>Fix NPE in querying spatial data through a sub-select.
<li>Fix NullPointerException in querying spatial data through a sub-select.
</li>
<li>Fix bug where a lock on the SYS table was not released when closing a session that contained a temp
table with an LOB column.
......@@ -71,7 +71,7 @@ table with an LOB column.
<li>Issue #231: Possible infinite loop when initializing the ObjectDataType class
when concurrently writing into MVStore.
</li>
<ul>
</ul>
<h2>Version 1.4.191 Beta (2016-01-21)</h2>
<ul>
......
......@@ -644,8 +644,7 @@ To keep the content of an in-memory database as long as the virtual machine is a
<h2 id="file_encryption">Database Files Encryption</h2>
<p>
The database files can be encrypted.
<p>
Three encryption algorithms are supported:
Three encryption algorithms are supported:
<ul>
<li>"AES" - also known as Rijndael, only AES-128 is implemented.</li>
<li>"XTEA" - the 32 round version.</li>
......
......@@ -495,7 +495,7 @@ for (int i = 0; i &lt; 400; i++) {
}
s.commit();
for (int i = 0; i &lt; 100; i++) {
map.put(0, "Hi");
map.put(i, "Hi");
}
s.commit();
s.close();
......@@ -511,7 +511,7 @@ will result in the following two chunks (excluding metadata):
</p>
<p>
<b>Chunk 2:</b><br />
- Page 4: (root) node with 2 entries pointing to page 3 and 5<br />
- Page 4: (root) node with 2 entries pointing to page 5 and 3<br />
- Page 5: leaf with 140 entries (keys 0 - 139)<br />
</p>
<p>
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto complete
toolbar.autoComplete.full=Full
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Off
toolbar.autoSelect=Auto select
toolbar.autoSelect.off=Off
toolbar.autoSelect.on=On
toolbar.cancelStatement=Cancel the current statement
toolbar.clear=Clear
toolbar.commit=Commit
......
......@@ -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);
}
......
......@@ -815,7 +815,10 @@ public class Session extends SessionWithState {
if (!closed) {
try {
database.checkPowerOff();
rollback(); // release any open table locks
// release any open table locks
rollback();
removeTemporaryLobs(false);
cleanTempTables(true);
undoLog.clear();
......@@ -934,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
......@@ -951,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);
}
......
......@@ -259,7 +259,7 @@ public class CompareLike extends Condition {
if (regexp) {
result = patternRegexp.matcher(value).find();
} else if (shortcutToStartsWith) {
result = value.regionMatches(ignoreCase, 0, patternString, 0, patternLength-1);
result = value.regionMatches(ignoreCase, 0, patternString, 0, patternLength - 1);
} else {
result = compareAt(value, 0, 0, value.length(), patternChars, patternTypes);
}
......@@ -388,7 +388,7 @@ public class CompareLike extends Condition {
while (maxMatch < patternLength && patternTypes[maxMatch] == MATCH) {
maxMatch++;
}
if (maxMatch == patternLength - 1 && patternTypes[patternLength-1] == ANY) {
if (maxMatch == patternLength - 1 && patternTypes[patternLength - 1] == ANY) {
shortcutToStartsWith = true;
}
}
......
......@@ -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);
......
......@@ -93,7 +93,11 @@ ALTER TABLE [ IF EXISTS ] tableName ADD constraint [ CHECK | NOCHECK ]
","
Adds a constraint to a table."
"Commands (DDL)","ALTER TABLE RENAME CONSTRAINT","
<<<<<<< HEAD
ALTER TABLE [ IF EXISTS ] tableName RENAME oldConstraintName TO newConstraintName
=======
ALTER TABLE tableName RENAME oldConstraintName TO newConstraintName
>>>>>>> upstream/master
","
Renames a constraint."
"Commands (DDL)","ALTER TABLE ALTER COLUMN","
......
......@@ -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";
......@@ -167,23 +169,22 @@ public class CipherFactory {
* Removes DH_anon and ECDH_anon from a comma separated list of ciphers.
* Only the first occurrence is removed.
* If there is nothing to remove, returns the reference to the argument.
* @param commaSepList a list of names separated by commas (and spaces)
* @param list a list of names separated by commas (and spaces)
* @return a new string without DH_anon and ECDH_anon items,
* or the original if none were found
*/
public static String removeDhAnonFromCommaSepList(String commaSepList) {
if (commaSepList == null) {
return commaSepList;
public static String removeDhAnonFromCommaSeparatedList(String list) {
if (list == null) {
return list;
}
List<String> algos = new LinkedList<String>(Arrays.asList(commaSepList.split("\\s*,\\s*")));
List<String> algos = new LinkedList<String>(Arrays.asList(list.split("\\s*,\\s*")));
boolean dhAnonRemoved = algos.remove("DH_anon");
boolean ecdhAnonRemoved = algos.remove("ECDH_anon");
if (dhAnonRemoved || ecdhAnonRemoved) {
String algosStr = Arrays.toString(algos.toArray(new String[algos.size()]));
return (algos.size() > 0) ? algosStr.substring(1, algosStr.length() - 1): "";
} else {
return commaSepList;
}
return list;
}
/**
......@@ -202,11 +203,11 @@ public class CipherFactory {
* behavior.
*/
public static synchronized void removeAnonFromLegacyAlgorithms() {
String legacyAlgosOrig = getLegacyAlgoritmsSilently();
String legacyAlgosOrig = getLegacyAlgorithmsSilently();
if (legacyAlgosOrig == null) {
return;
}
String legacyAlgosNew = removeDhAnonFromCommaSepList(legacyAlgosOrig);
String legacyAlgosNew = removeDhAnonFromCommaSeparatedList(legacyAlgosOrig);
if (!legacyAlgosOrig.equals(legacyAlgosNew)) {
setLegacyAlgorithmsSilently(legacyAlgosNew);
}
......@@ -228,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);
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Automatické dokončování
toolbar.autoComplete.full=Úplné
toolbar.autoComplete.normal=Normální
toolbar.autoComplete.off=Vypnuto
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Vypnuto
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Zrušit prováděný příkaz
toolbar.clear=Vyčistit
toolbar.commit=Vložit
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto-Complete
toolbar.autoComplete.full=Alles
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Aus
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Aus
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Laufenden Befehl abbrechen
toolbar.clear=Leeren
toolbar.commit=Commit (Abschliessen/Speichern)
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto completado
toolbar.autoComplete.full=Completo
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Desactivado
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Desactivado
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Cancelar la instrucción actual
toolbar.clear=Eliminar
toolbar.commit=Commit
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Complètement automatique
toolbar.autoComplete.full=Exhaustif
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Désactivé
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Désactivé
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Annuler l'instruction en cours
toolbar.clear=Effacer
toolbar.commit=Valider
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Automatikus kiegészítés
toolbar.autoComplete.full=Teljes
toolbar.autoComplete.normal=Normál
toolbar.autoComplete.off=Kikapcsolva
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Kikapcsolva
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Aktuális utasítás végrehajtásának megszakítása
toolbar.clear=Törlés
toolbar.commit=Jóváhagyás
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto-Complete
toolbar.autoComplete.full=Full
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Off
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Off
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Batalkan pernyataan terkini
toolbar.clear=Bersihkan
toolbar.commit=Laksanakan
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto completamento
toolbar.autoComplete.full=Pieno
toolbar.autoComplete.normal=Normale
toolbar.autoComplete.off=Disattivo
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Disattivo
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Annulla il seguente comando
toolbar.clear=Annulla
toolbar.commit=Esegui comando
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=オートコンプリート
toolbar.autoComplete.full=フル
toolbar.autoComplete.normal=ノーマル
toolbar.autoComplete.off=オフ
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=オフ
toolbar.autoSelect.on=#On
toolbar.cancelStatement=現在のステートメントをキャンセル
toolbar.clear=クリア
toolbar.commit=コミット
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=자동 완성
toolbar.autoComplete.full=전체
toolbar.autoComplete.normal=보통
toolbar.autoComplete.off=안함
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=안함
toolbar.autoSelect.on=#On
toolbar.cancelStatement=현재 문 취소
toolbar.clear=지우기
toolbar.commit=커밋
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto aanvullen
toolbar.autoComplete.full=Volledig
toolbar.autoComplete.normal=Normaal
toolbar.autoComplete.off=Uit
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Uit
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Annuleer het huidige statement
toolbar.clear=Wissen
toolbar.commit=Commit
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Automatyczne uzupełnianie
toolbar.autoComplete.full=Pełny
toolbar.autoComplete.normal=Normalny
toolbar.autoComplete.off=Wyłączony
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Wyłączony
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Anuluj bieżące zapytanie
toolbar.clear=Wyczyść
toolbar.commit=Zatwierdź
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto complete
toolbar.autoComplete.full=Total
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Desligado
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Desligado
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Cancelar o comando que se encontra em execução
toolbar.clear=Limpar
toolbar.commit=Commit
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Авто-завершение
toolbar.autoComplete.full=Все
toolbar.autoComplete.normal=Нормальные
toolbar.autoComplete.off=Выключено
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Выключено
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Отменить текущий запрос
toolbar.clear=Очистить
toolbar.commit=Выполнить
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto dokončovanie
toolbar.autoComplete.full=Plné
toolbar.autoComplete.normal=Normálne
toolbar.autoComplete.off=Vypnuté
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Vypnuté
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Zrušiť aktuálny príkaz
toolbar.clear=Vyčistiť
toolbar.commit=Commit (schváliť)
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Auto-Complete
toolbar.autoComplete.full=Hepsi
toolbar.autoComplete.normal=Normal
toolbar.autoComplete.off=Kapalı
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Kapalı
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Yürütülen işlemi iptal et
toolbar.clear=Temizle
toolbar.commit=Degişiklikleri kaydet
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=Авто доповнення
toolbar.autoComplete.full=Повне
toolbar.autoComplete.normal=Нормальне
toolbar.autoComplete.off=Виключене
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=Виключене
toolbar.autoSelect.on=#On
toolbar.cancelStatement=Відмінити поточний запит
toolbar.clear=Очистити
toolbar.commit=Підтвердити зміни
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=自动完成
toolbar.autoComplete.full=完全
toolbar.autoComplete.normal=正常
toolbar.autoComplete.off=关闭
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=关闭
toolbar.autoSelect.on=#On
toolbar.cancelStatement=取消当前的执行语句
toolbar.clear=清除
toolbar.commit=提交
......
......@@ -98,6 +98,9 @@ toolbar.autoComplete=自動完成 (complete)
toolbar.autoComplete.full=完整
toolbar.autoComplete.normal=標準
toolbar.autoComplete.off=關閉
toolbar.autoSelect=#Auto select
toolbar.autoSelect.off=關閉
toolbar.autoSelect.on=#On
toolbar.cancelStatement=取消目前的SQL述句
toolbar.clear=清除
toolbar.commit=提交
......
......@@ -553,6 +553,7 @@ public class Data {
writeVarInt(ts.getTimeZoneOffsetMins());
}
case Value.GEOMETRY:
// fall though
case Value.JAVA_OBJECT: {
writeByte((byte) type);
byte[] b = v.getBytesNoCopy();
......@@ -792,7 +793,7 @@ public class Data {
case Value.TIMESTAMP_TZ: {
long dateValue = readVarLong();
long nanos = readVarLong();
short tz = (short)readVarInt();
short tz = (short) readVarInt();
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz);
}
case Value.BYTES: {
......
......@@ -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()) {
......
......@@ -248,6 +248,7 @@ public abstract class Table extends SchemaObjectBase {
* @param filters the table filters
* @param filter the filter index
* @param sortOrder the sort order
* @param allColumnsSet all columns
* @return the scan index
*/
public Index getScanIndex(Session session, int[] masks,
......@@ -702,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,
......@@ -719,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) {
......@@ -565,7 +571,7 @@ public class TableView extends Table {
return result + 1;
}
private int getMaxParameterIndex(ArrayList<Parameter> parameters) {
private static int getMaxParameterIndex(ArrayList<Parameter> parameters) {
int result = -1;
for (Parameter p : parameters) {
result = Math.max(result, p.getIndex());
......
......@@ -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);
......
......@@ -148,8 +148,9 @@ class ToDateTokenizer {
dateNr = Integer.parseInt(inputFragmentStr);
// Gregorian calendar does not have a year 0.
// 0 = 0001 BC, -1 = 0002 BC, ... so we adjust
if (dateNr==0)
if (dateNr == 0) {
throwException(params, "Year may not be zero");
}
result.set(Calendar.YEAR, dateNr >= 0 ? dateNr : dateNr + 1);
break;
case YYY:
......@@ -166,13 +167,15 @@ class ToDateTokenizer {
PATTERN_TWO_TO_FOUR_DIGITS, params, formatTokenEnum);
dateNr = Integer.parseInt(inputFragmentStr);
if (inputFragmentStr.length() < 4) {
if (dateNr < 50)
if (dateNr < 50) {
dateNr += 2000;
else if (dateNr < 100)
} else if (dateNr < 100) {
dateNr += 1900;
}
}
if (dateNr==0)
if (dateNr == 0) {
throwException(params, "Year may not be zero");
}
result.set(Calendar.YEAR, dateNr);
break;
case RR:
......
......@@ -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);
if (timeZoneOffsetMins < (-12 * 60) || timeZoneOffsetMins >= (12 * 60)) {
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);
......@@ -149,7 +161,7 @@ public class ValueTimestampTimeZone extends Value {
}
long dateValue = DateTimeUtils.parseDateValue(s, 0, dateEnd);
long nanos;
short tz_mins = 0;
short tzMinutes = 0;
if (timeStart < 0) {
nanos = 0;
} else {
......@@ -183,12 +195,13 @@ public class ValueTimestampTimeZone extends Value {
}
if (tz != null) {
long millis = DateTimeUtils.convertDateValueToDate(dateValue).getTime();
tz_mins = (short) (tz.getOffset(millis) / 1000 / 60);
tzMinutes = (short) (tz.getOffset(millis) / 1000 / 60);
}
}
nanos = DateTimeUtils.parseTimeNanos(s, dateEnd + 1, timeEnd, true);
}
return ValueTimestampTimeZone.fromDateValueAndNanos(dateValue, nanos, tz_mins);
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
......@@ -250,7 +265,7 @@ public class ValueTimestampTimeZone extends Value {
private static void appendTimeZone(StringBuilder buff, short tz) {
if (tz < 0) {
buff.append('-');
tz = (short)-tz;
tz = (short) -tz;
}
int hours = tz / 60;
tz -= hours * 60;
......@@ -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");
}
}
......@@ -12,7 +12,10 @@ import org.junit.Test;
* used by H2.
*/
public class TestAllJunit {
/**
* Run all the fast tests.
*/
@Test
public void testFast() throws Exception {
TestAll.main("fast");
......
......@@ -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,21 +1407,23 @@ 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"));
assertEquals(ymd.parse("9999-03-01"), ToDateParser.toDate("1-MAR-9999","DD-MON-RRRR"));
assertEquals(ymd.parse("2000-03-01"), ToDateParser.toDate("1-MAR-000","DD-MON-RRRR"));
assertEquals(ymd.parse("1999-03-01"), ToDateParser.toDate("1-MAR-099","DD-MON-RRRR"));
assertEquals(ymd.parse("0100-03-01"), ToDateParser.toDate("1-MAR-100","DD-MON-RRRR"));
assertEquals(ymd.parse("2000-03-01"), ToDateParser.toDate("1-MAR-00","DD-MON-RRRR"));
assertEquals(ymd.parse("2049-03-01"), ToDateParser.toDate("1-MAR-49","DD-MON-RRRR"));
assertEquals(ymd.parse("1950-03-01"), ToDateParser.toDate("1-MAR-50","DD-MON-RRRR"));
assertEquals(ymd.parse("1999-03-01"), ToDateParser.toDate("1-MAR-99","DD-MON-RRRR"));
assertEquals(ymd.parse("0001-03-01"), ToDateParser.toDate("1-MAR-0001", "DD-MON-RRRR"));
assertEquals(ymd.parse("9999-03-01"), ToDateParser.toDate("1-MAR-9999", "DD-MON-RRRR"));
assertEquals(ymd.parse("2000-03-01"), ToDateParser.toDate("1-MAR-000", "DD-MON-RRRR"));
assertEquals(ymd.parse("1999-03-01"), ToDateParser.toDate("1-MAR-099", "DD-MON-RRRR"));
assertEquals(ymd.parse("0100-03-01"), ToDateParser.toDate("1-MAR-100", "DD-MON-RRRR"));
assertEquals(ymd.parse("2000-03-01"), ToDateParser.toDate("1-MAR-00", "DD-MON-RRRR"));
assertEquals(ymd.parse("2049-03-01"), ToDateParser.toDate("1-MAR-49", "DD-MON-RRRR"));
assertEquals(ymd.parse("1950-03-01"), ToDateParser.toDate("1-MAR-50", "DD-MON-RRRR"));
assertEquals(ymd.parse("1999-03-01"), ToDateParser.toDate("1-MAR-99", "DD-MON-RRRR"));
}
private static void setMonth(Date date, int month) {
......@@ -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
......
......@@ -37,7 +37,8 @@ public class TestConnection extends TestBase {
}
private void testSetInternalProperty() throws SQLException {
// Use MySQL-mode since this allows all property names (apart from h2 internal names).
// Use MySQL-mode since this allows all property names
// (apart from h2 internal names).
Connection conn = getConnection("clientInfoMySQL;MODE=MySQL");
assertThrows(SQLClientInfoException.class, conn).setClientInfo("numServers", "SomeValue");
......@@ -48,7 +49,7 @@ public class TestConnection extends TestBase {
Connection conn = getConnection("clientInfo");
Properties properties = new Properties();
properties.put("ClientUser", "someuser");
properties.put("ClientUser", "someUser");
assertThrows(SQLClientInfoException.class, conn).setClientInfo(properties);
}
......@@ -58,12 +59,12 @@ public class TestConnection extends TestBase {
conn.setClientInfo("ApplicationName", "Connection Test");
Properties properties = new Properties();
properties.put("ClientUser", "someuser");
properties.put("ClientUser", "someUser");
conn.setClientInfo(properties);
// old property should have been removed
assertNull(conn.getClientInfo("ApplicationName"));
// new property has been set
assertEquals(conn.getClientInfo("ClientUser"), "someuser");
assertEquals(conn.getClientInfo("ClientUser"), "someUser");
}
private void testSetSupportedClientInfo() throws SQLException {
......@@ -75,7 +76,8 @@ public class TestConnection extends TestBase {
private void testSetUnsupportedClientInfo() throws SQLException {
Connection conn = getConnection("clientInfoDB2;MODE=DB2");
assertThrows(SQLClientInfoException.class, conn).setClientInfo("UnsupportedName", "SomeValue");
assertThrows(SQLClientInfoException.class, conn).setClientInfo(
"UnsupportedName", "SomeValue");
}
private void testGetUnsupportedClientInfo() throws SQLException {
......
......@@ -132,7 +132,7 @@ public class CalculateHashConstantLong implements Runnable {
System.out.println("Collisions: " + collisions);
}
static void printQuality(CalculateHashConstantLong test, long[] randomValues) {
private static void printQuality(CalculateHashConstantLong test, long[] randomValues) {
int finalCount = randomValues.length * 10;
System.out.println("Quality of " + test);
int[] minMax;
......
......@@ -10212,13 +10212,13 @@ insert into test values(5, 'b'), (5, 'b'), (20, 'a');
> update count: 3
select 0 from ((
select 0 as f from dual u1 where null in (?, ?, ?, ?, ?)
select 0 as f from dual u1 where null in (?, ?, ?, ?, ?)
) union all (
select u2.f from (
select 0 as f from (
select 0 from dual u2f1f1 where now() = ?
) u2f1
) u2
select u2.f from (
select 0 as f from (
select 0 from dual u2f1f1 where now() = ?
) u2f1
) u2
)) where f = 12345;
{
11, 22, 33, 44, 55, null
......
......@@ -36,12 +36,17 @@ public class TestMode extends TestBase {
private void testDb2ClientInfo() {
Mode db2Mode = Mode.getInstance("DB2");
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher("ApplicationName").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher("ClientAccountingInformation").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher("ClientUser").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher("ClientCorrelationToken").matches());
assertFalse(db2Mode.supportedClientInfoPropertiesRegEx.matcher("AnyOtherValue").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher(
"ApplicationName").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher(
"ClientAccountingInformation").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher(
"ClientUser").matches());
assertTrue(db2Mode.supportedClientInfoPropertiesRegEx.matcher(
"ClientCorrelationToken").matches());
assertFalse(db2Mode.supportedClientInfoPropertiesRegEx.matcher(
"AnyOtherValue").matches());
}
private void testDerbyClientInfo() {
......@@ -61,22 +66,25 @@ public class TestMode extends TestBase {
private void testMySqlClientInfo() {
Mode mySqlMode = Mode.getInstance("MySQL");
assertTrue(mySqlMode.supportedClientInfoPropertiesRegEx.matcher("AnyString").matches());
assertTrue(mySqlMode.supportedClientInfoPropertiesRegEx.matcher(
"AnyString").matches());
}
private void testOracleClientInfo() {
Mode oracleMode = Mode.getInstance("Oracle");
assertTrue(oracleMode.supportedClientInfoPropertiesRegEx.matcher("anythingContaining.aDot").matches());
assertFalse(oracleMode.supportedClientInfoPropertiesRegEx.matcher("anythingContainingNoDot").matches());
assertTrue(oracleMode.supportedClientInfoPropertiesRegEx.matcher(
"anythingContaining.aDot").matches());
assertFalse(oracleMode.supportedClientInfoPropertiesRegEx.matcher(
"anythingContainingNoDot").matches());
}
private void testPostgresqlClientInfo() {
Mode postgresqlMode = Mode.getInstance("PostgreSQL");
assertTrue(postgresqlMode.supportedClientInfoPropertiesRegEx.matcher("ApplicationName").matches());
assertFalse(postgresqlMode.supportedClientInfoPropertiesRegEx.matcher("AnyOtherValue").matches());
assertTrue(postgresqlMode.supportedClientInfoPropertiesRegEx.matcher(
"ApplicationName").matches());
assertFalse(postgresqlMode.supportedClientInfoPropertiesRegEx.matcher(
"AnyOtherValue").matches());
}
}
......@@ -140,7 +140,7 @@ public class TestNetUtils extends TestBase {
private Task createServerSocketTask(final ServerSocket serverSocket) {
Task task = new Task() {
@Override
public void call() throws Exception {
Socket ss = null;
......@@ -148,14 +148,19 @@ public class TestNetUtils extends TestBase {
ss = serverSocket.accept();
ss.getOutputStream().write(123);
} finally {
closeSilently(ss);
closeSilently(ss);
}
}
};
return task;
}
private void closeSilently(Socket socket) {
/**
* Close a socket, ignoring errors
*
* @param socket the socket
*/
void closeSilently(Socket socket) {
try {
socket.close();
} catch (Exception e) {
......@@ -163,7 +168,12 @@ public class TestNetUtils extends TestBase {
}
}
private void closeSilently(ServerSocket socket) {
/**
* Close a server socket, ignoring errors
*
* @param socket the server socket
*/
void closeSilently(ServerSocket socket) {
try {
socket.close();
} catch (Exception e) {
......
......@@ -36,7 +36,7 @@ public class TestSecurity extends TestBase {
testSHA();
testAES();
testBlockCiphers();
testRemoveAnonFromLegacyAlgos();
testRemoveAnonFromLegacyAlgorithms();
//testResetLegacyAlgos();
}
......@@ -254,7 +254,7 @@ public class TestSecurity extends TestBase {
return len * r < len * 120;
}
private void testRemoveAnonFromLegacyAlgos() {
private void testRemoveAnonFromLegacyAlgorithms() {
String legacyAlgos = "K_NULL, C_NULL, M_NULL, DHE_DSS_EXPORT" +
", DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, RSA_EXPORT" +
", DH_anon, ECDH_anon, RC4_128, RC4_40, DES_CBC, DES40_CBC";
......@@ -262,15 +262,15 @@ public class TestSecurity extends TestBase {
", DHE_RSA_EXPORT, DH_anon_EXPORT, DH_DSS_EXPORT, DH_RSA_EXPORT, RSA_EXPORT" +
", RC4_128, RC4_40, DES_CBC, DES40_CBC";
assertEquals(expectedLegacyAlgosWithoutDhAnon,
CipherFactory.removeDhAnonFromCommaSepList(legacyAlgos));
CipherFactory.removeDhAnonFromCommaSeparatedList(legacyAlgos));
legacyAlgos = "ECDH_anon, DH_anon_EXPORT, DH_anon";
expectedLegacyAlgosWithoutDhAnon = "DH_anon_EXPORT";
assertEquals(expectedLegacyAlgosWithoutDhAnon,
CipherFactory.removeDhAnonFromCommaSepList(legacyAlgos));
CipherFactory.removeDhAnonFromCommaSeparatedList(legacyAlgos));
legacyAlgos = null;
assertNull(CipherFactory.removeDhAnonFromCommaSepList(legacyAlgos));
assertNull(CipherFactory.removeDhAnonFromCommaSeparatedList(legacyAlgos));
}
/**
......@@ -282,13 +282,13 @@ public class TestSecurity extends TestBase {
*/
@SuppressWarnings("unused")
private void testResetLegacyAlgos() {
String legacyAlgorithmsBefore = CipherFactory.getLegacyAlgoritmsSilently();
String legacyAlgorithmsBefore = CipherFactory.getLegacyAlgorithmsSilently();
assertEquals("Failed assumption: jdk.tls.legacyAlgorithms" +
" has been modified from its initial setting",
CipherFactory.DEFAULT_LEGACY_ALGORITHMS, legacyAlgorithmsBefore);
CipherFactory.removeAnonFromLegacyAlgorithms();
CipherFactory.resetDefaultLegacyAlgorithms();
String legacyAlgorithmsAfter = CipherFactory.getLegacyAlgoritmsSilently();
String legacyAlgorithmsAfter = CipherFactory.getLegacyAlgorithmsSilently();
assertEquals(CipherFactory.DEFAULT_LEGACY_ALGORITHMS, legacyAlgorithmsAfter);
}
......
......@@ -39,7 +39,7 @@ public class TestTimeStampWithTimeZone extends TestBase {
stat.execute("insert into test(t1) values('1970-01-01 12:00:00.00+00:15')");
ResultSet rs = stat.executeQuery("select t1 from test");
rs.next();
assertTrue(new TimestampWithTimeZone(36000000, 00, (short)15).equals(rs.getTimestamp(1)));
assertTrue(new TimestampWithTimeZone(36000000, 00, (short) 15).equals(rs.getTimestamp(1)));
conn.close();
}
......
......@@ -167,7 +167,7 @@ public class TestValueMemory extends TestBase implements DataHandler {
case Value.TIMESTAMP_UTC:
return ValueTimestampUtc.fromMillis(random.nextLong());
case Value.TIMESTAMP_TZ:
return ValueTimestampTimeZone.fromMillis(random.nextLong(), (short)0);
return ValueTimestampTimeZone.fromMillis(random.nextLong(), (short) 0);
case Value.BYTES:
return ValueBytes.get(randomBytes(random.nextInt(1000)));
case Value.STRING:
......
......@@ -6,7 +6,7 @@
*
* You can obtain a copy of the license at
* glassfish/bootstrap/legal/CDDLv1.0.txt or
* https://glassfish.dev.java.net/public/CDDLv1.0.html.
* https://glassfish.dev.java.net/public/CDDLv1.0.html .
* See the License for the specific language governing
* permissions and limitations under the License.
*
......
......@@ -238,7 +238,8 @@ public class Build extends BuildBase {
if (!clientOnly) {
files = files("src/test");
files.addAll(files("src/tools"));
files = files.exclude("src/test/org/h2/test/TestAllJunit.java"); //we don't use Junit for this test framework
//we don't use Junit for this test framework
files = files.exclude("src/test/org/h2/test/TestAllJunit.java");
args = args("-Xlint:unchecked", "-Xlint:deprecation",
"-d", "temp", "-sourcepath", "src/test" + File.pathSeparator + "src/tools",
"-classpath", classpath);
......
......@@ -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
......
......@@ -99,8 +99,9 @@ public class CheckJavadoc {
}
if (inComment) {
if (rawLine.length() > MAX_COMMENT_LINE_SIZE
&& !line.trim().startsWith("* http://")) {
System.out.println("Long line : " + file.getAbsolutePath()
&& !line.trim().startsWith("* http://")
&& !line.trim().startsWith("* https://")) {
System.out.println("Long line: " + file.getAbsolutePath()
+ " (" + file.getName() + ":" + lineNumber + ")");
errorCount++;
}
......@@ -108,12 +109,14 @@ public class CheckJavadoc {
inComment = false;
}
}
if (!inComment && line.startsWith("//")
&& rawLine.length() > MAX_COMMENT_LINE_SIZE
&& !line.trim().startsWith("// http://")) {
System.out.println("Long line: " + file.getAbsolutePath()
+ " (" + file.getName() + ":" + lineNumber + ")");
errorCount++;
if (!inComment && line.startsWith("//")) {
if (rawLine.length() > MAX_COMMENT_LINE_SIZE
&& !line.trim().startsWith("// http://")
&& !line.trim().startsWith("// https://")) {
System.out.println("Long line: " + file.getAbsolutePath()
+ " (" + file.getName() + ":" + lineNumber + ")");
errorCount++;
}
} else if (!inComment && rawLine.length() > MAX_SOURCE_LINE_SIZE) {
System.out.println("Long line: " + file.getAbsolutePath()
+ " (" + file.getName() + ":" + lineNumber + ")");
......
......@@ -11,6 +11,8 @@ import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.build.BuildBase;
import org.h2.util.StringUtils;
......@@ -72,6 +74,11 @@ public class SpellChecker {
private void run(String dictionaryFileName, String dir) throws IOException {
process(new File(dictionaryFileName));
process(new File(dir));
HashSet<String> unused = new HashSet<String>();
unused.addAll(dictionary);
unused.removeAll(used);
// System.out.println("UNUSED WORDS");
// System.out.println(unused);
if (printDictionary) {
System.out.println("USED WORDS");
String[] list = new String[used.size()];
......@@ -190,19 +197,20 @@ public class SpellChecker {
}
private String removeLinks(String fileName, String text) {
Pattern linkPattern = Pattern.compile("http[s]?://");
StringBuilder buff = new StringBuilder(text.length());
int pos = 0, last = 0;
if (fileName.endsWith(".properties")) {
text = StringUtils.replaceAll(text, "\\:", ":");
}
while (true) {
pos = text.indexOf("http://", pos);
if (pos < 0) {
Matcher m = linkPattern.matcher(text.substring(pos));
if (!m.find()) {
break;
}
int start = pos;
int start = m.start() + pos;
pos = m.end() + pos;
buff.append(text.substring(last, start));
pos += "http://".length();
while (true) {
char c = text.charAt(pos);
if (!Character.isJavaIdentifierPart(c) &&
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论