Unverified 提交 15476b8b authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1562 from katzyn/misc

Assorted minor changes
......@@ -21,6 +21,12 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1561: Incorrect documentation and strange fallback value of SysProperties.FILE_ENCODING
</li>
<li>PR #1557: increase lock timeout to TestConcurrentUpdate due to Travis failures
</li>
<li>Issue #1554: REGEXP_REPLACE - accept 'g' flag in PostgreSQL compatibility mode
</li>
<li>Issue #950: Comparison between databases in README.md and in features.html
</li>
<li>Issue #1549: [RFE] Implement locking modes (select for update)
......
......@@ -5,6 +5,8 @@
*/
package org.h2.engine;
import java.io.File;
import org.h2.util.MathUtils;
import org.h2.util.Utils;
......@@ -42,26 +44,16 @@ public class SysProperties {
public static final String H2_BROWSER = "h2.browser";
/**
* System property <code>file.encoding</code> (default: Cp1252).<br />
* It is usually set by the system and is the default encoding used for the
* RunScript and CSV tool.
*/
public static final String FILE_ENCODING =
Utils.getProperty("file.encoding", "Cp1252");
/**
* System property <code>file.separator</code> (default: /).<br />
* It is usually set by the system, and used to build absolute file names.
* System property <code>file.separator</code>.<br />
* It is set by the system, and used to build absolute file names.
*/
public static final String FILE_SEPARATOR =
Utils.getProperty("file.separator", "/");
public static final String FILE_SEPARATOR = File.separator;
/**
* System property <code>line.separator</code> (default: \n).<br />
* It is usually set by the system, and used by the script and trace tools.
* System property <code>line.separator</code>.<br />
* It is set by the system, and used by the script and trace tools.
*/
public static final String LINE_SEPARATOR =
Utils.getProperty("line.separator", "\n");
public static final String LINE_SEPARATOR = System.lineSeparator();
/**
* System property <code>user.home</code> (empty string if not set).<br />
......
......@@ -17,6 +17,7 @@ import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
......@@ -1350,50 +1351,11 @@ public class Function extends Expression implements FunctionCall {
break;
}
case REGEXP_REPLACE: {
String input = v0.getString();
String regexp = v1.getString();
String replacement = v2.getString();
if (database.getMode().regexpReplaceBackslashReferences) {
if ((replacement.indexOf('\\') >= 0) || (replacement.indexOf('$') >= 0)) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < replacement.length(); i++) {
char c = replacement.charAt(i);
if (c == '$') {
sb.append('\\');
} else if (c == '\\' && ++i < replacement.length()) {
c = replacement.charAt(i);
sb.append(c >= '0' && c <= '9' ? '$' : '\\');
}
sb.append(c);
}
replacement = sb.toString();
}
}
String regexpMode = v3 == null || v3.getString() == null ? "" :
v3.getString();
boolean isInPostgreSqlMode = Mode.ModeEnum.PostgreSQL.equals(database.getMode().getEnum());
int flags = makeRegexpFlags(regexpMode, isInPostgreSqlMode);
try {
if(isInPostgreSqlMode && !regexpMode.contains("g")) {
result = ValueString.get(
Pattern.compile(regexp, flags).matcher(v0.getString())
.replaceFirst(replacement),
database.getMode().treatEmptyStringsAsNull);
} else {
result = ValueString.get(
Pattern.compile(regexp, flags).matcher(v0.getString())
.replaceAll(replacement),
database.getMode().treatEmptyStringsAsNull);
}
} catch (StringIndexOutOfBoundsException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
} catch (PatternSyntaxException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
} catch (IllegalArgumentException e) {
throw DbException.get(
ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
}
String regexpMode = v3 != null ? v3.getString() : null;
result = regexpReplace(input, regexp, replacement, regexpMode);
break;
}
case RPAD:
......@@ -1656,8 +1618,7 @@ public class Function extends Expression implements FunctionCall {
break;
case REGEXP_LIKE: {
String regexp = v1.getString();
String regexpMode = v2 == null || v2.getString() == null ? "" :
v2.getString();
String regexpMode = v2 != null ? v2.getString() : null;
int flags = makeRegexpFlags(regexpMode, false);
try {
result = ValueBoolean.get(Pattern.compile(regexp, flags)
......@@ -2040,6 +2001,40 @@ public class Function extends Expression implements FunctionCall {
return md;
}
private Value regexpReplace(String input, String regexp, String replacement, String regexpMode) {
Mode mode = database.getMode();
if (mode.regexpReplaceBackslashReferences) {
if ((replacement.indexOf('\\') >= 0) || (replacement.indexOf('$') >= 0)) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < replacement.length(); i++) {
char c = replacement.charAt(i);
if (c == '$') {
sb.append('\\');
} else if (c == '\\' && ++i < replacement.length()) {
c = replacement.charAt(i);
sb.append(c >= '0' && c <= '9' ? '$' : '\\');
}
sb.append(c);
}
replacement = sb.toString();
}
}
boolean isInPostgreSqlMode = Mode.ModeEnum.PostgreSQL.equals(mode.getEnum());
int flags = makeRegexpFlags(regexpMode, isInPostgreSqlMode);
try {
Matcher matcher = Pattern.compile(regexp, flags).matcher(input);
return ValueString.get(isInPostgreSqlMode && (regexpMode == null || regexpMode.indexOf('g') < 0) ?
matcher.replaceFirst(replacement) : matcher.replaceAll(replacement),
mode.treatEmptyStringsAsNull);
} catch (StringIndexOutOfBoundsException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
} catch (PatternSyntaxException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, regexp);
} catch (IllegalArgumentException e) {
throw DbException.get(ErrorCode.LIKE_ESCAPE_ERROR_1, e, replacement);
}
}
private static int makeRegexpFlags(String stringFlags, boolean ignoreGlobalFlag) {
int flags = Pattern.UNICODE_CASE;
if (stringFlags != null) {
......
......@@ -44,7 +44,7 @@ public class Csv implements SimpleRowSource {
private String[] columnNames;
private String characterSet = SysProperties.FILE_ENCODING;
private String characterSet;
private char escapeCharacter = '\"';
private char fieldDelimiter = '\"';
private char fieldSeparatorRead = ',';
......@@ -136,7 +136,6 @@ public class Csv implements SimpleRowSource {
* @param rs the result set - the result set must be positioned before the
* first row.
* @param charset the charset or null to use the system default charset
* (see system property file.encoding)
* @return the number of rows written
*/
public int write(String outputFileName, ResultSet rs, String charset)
......@@ -184,7 +183,6 @@ public class Csv implements SimpleRowSource {
* @param colNames or null if the column names should be read from the CSV
* file
* @param charset the charset or null to use the system default charset
* (see system property file.encoding)
* @return the result set
*/
public ResultSet read(String inputFileName, String[] colNames,
......@@ -246,9 +244,7 @@ public class Csv implements SimpleRowSource {
private void init(String newFileName, String charset) {
this.fileName = newFileName;
if (charset != null) {
this.characterSet = charset;
}
this.characterSet = charset;
}
private void initWrite() throws IOException {
......@@ -256,7 +252,8 @@ public class Csv implements SimpleRowSource {
try {
OutputStream out = FileUtils.newOutputStream(fileName, false);
out = new BufferedOutputStream(out, Constants.IO_BUFFER_SIZE);
output = new BufferedWriter(new OutputStreamWriter(out, characterSet));
output = new BufferedWriter(characterSet != null ?
new OutputStreamWriter(out, characterSet) : new OutputStreamWriter(out));
} catch (Exception e) {
close();
throw DbException.convertToIOException(e);
......@@ -314,7 +311,7 @@ public class Csv implements SimpleRowSource {
try {
InputStream in = FileUtils.newInputStream(fileName);
in = new BufferedInputStream(in, Constants.IO_BUFFER_SIZE);
input = new InputStreamReader(in, characterSet);
input = characterSet != null ? new InputStreamReader(in, characterSet) : new InputStreamReader(in);
} catch (IOException e) {
close();
throw e;
......
......@@ -166,7 +166,7 @@ public class Profiler implements Runnable {
}
continue;
}
try (Reader reader = new InputStreamReader(new FileInputStream(arg), "CP1252")) {
try (Reader reader = new InputStreamReader(new FileInputStream(arg))) {
LineNumberReader r = new LineNumberReader(reader);
while (true) {
String line = r.readLine();
......@@ -177,7 +177,7 @@ public class Profiler implements Runnable {
}
}
}
try (Reader reader = new InputStreamReader(new FileInputStream(arg), "CP1252")) {
try (Reader reader = new InputStreamReader(new FileInputStream(arg))) {
LineNumberReader r = new LineNumberReader(reader);
processList(readStackTrace(r));
}
......
......@@ -8,6 +8,7 @@ package org.h2.test.scripts;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.nio.charset.StandardCharsets;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
......@@ -46,8 +47,7 @@ public class TestScriptSimple extends TestDb {
reconnect();
String inFile = "org/h2/test/scripts/testSimple.in.txt";
InputStream is = getClass().getClassLoader().getResourceAsStream(inFile);
LineNumberReader lineReader = new LineNumberReader(
new InputStreamReader(is, "Cp1252"));
LineNumberReader lineReader = new LineNumberReader(new InputStreamReader(is, StandardCharsets.UTF_8));
try (ScriptReader reader = new ScriptReader(lineReader)) {
while (true) {
String sql = reader.readStatement();
......
......@@ -802,3 +802,4 @@ partitioned tri partitions
discard enhancements nolock surefire logarithm
qualification opportunity jumping exploited unacceptable vrs duplicated
queryparser tokenized freeze factorings recompilation unenclosed rfe dsync
econd irst bcef
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论