Unverified 提交 4be14cbf authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov 提交者: GitHub

Merge pull request #1542 from katzyn/misc

Reduce GC pressure
......@@ -21,6 +21,14 @@ Change Log
<h2>Next Version (unreleased)</h2>
<ul>
<li>Issue #1534: Typo in message
</li>
<li>Issue #1527: Parser performance: Excessive use of regular expressions to validate column names
</li>
<li>PR #1543: MVStore assorted re-factorings
</li>
<li>PR #1538: Add support for newer Lucene versions without recompilation
</li>
<li>Issue #1536: CURRENT_TIMESTAMP result doesn't change under Transactions
</li>
<li>Issue #239: Consider supporting Lucene 5 indexes
......
......@@ -628,7 +628,8 @@ public final class Interval {
@Override
public String toString() {
return IntervalUtils.intervalToString(qualifier, negative, leading, remaining);
return IntervalUtils.appendInterval(new StringBuilder(), getQualifier(), negative, leading, remaining)
.toString();
}
}
......@@ -7,6 +7,7 @@ package org.h2.api;
import java.io.Serializable;
import org.h2.util.DateTimeUtils;
import org.h2.value.ValueTimestampTimeZone;
/**
* How we expose "TIMESTAMP WITH TIME ZONE" in our ResultSets.
......@@ -109,7 +110,9 @@ public class TimestampWithTimeZone implements Serializable, Cloneable {
@Override
public String toString() {
return DateTimeUtils.timestampTimeZoneToString(dateValue, timeNanos, timeZoneOffsetMins);
StringBuilder builder = new StringBuilder(ValueTimestampTimeZone.MAXIMUM_PRECISION);
DateTimeUtils.appendTimestampTimeZone(builder, dateValue, timeNanos, timeZoneOffsetMins);
return builder.toString();
}
@Override
......
......@@ -2687,9 +2687,14 @@ public class Parser {
}
private void setSQL(Prepared command, String start, int startIndex) {
String sql = StringUtils.trimSubstring(originalSQL, startIndex, lastParseIndex);
int endIndex = lastParseIndex;
String sql;
if (start != null) {
sql = start + " " + sql;
StringBuilder builder = new StringBuilder(start.length() + endIndex - startIndex + 1)
.append(start).append(' ');
sql = StringUtils.trimSubstring(builder, originalSQL, startIndex, endIndex).toString();
} else {
sql = StringUtils.trimSubstring(originalSQL, startIndex, endIndex);
}
command.setSQL(sql);
}
......@@ -2743,16 +2748,13 @@ public class Parser {
// special case: NOT NULL is not part of an expression (as in CREATE
// TABLE TEST(ID INT DEFAULT 0 NOT NULL))
int backup = parseIndex;
boolean not = false;
if (readIf(NOT)) {
not = true;
if (isToken(NULL)) {
// this really only works for NOT NULL!
parseIndex = backup;
currentToken = "NOT";
currentTokenType = NOT;
break;
}
boolean not = readIf(NOT);
if (not && isToken(NULL)) {
// this really only works for NOT NULL!
parseIndex = backup;
currentToken = "NOT";
currentTokenType = NOT;
break;
}
if (readIf(LIKE)) {
Expression b = readConcat();
......@@ -2841,6 +2843,9 @@ public class Parser {
Comparison.BIGGER_EQUAL, high, r);
r = new ConditionAndOr(ConditionAndOr.AND, condLow, condHigh);
} else {
if (not) {
throw getSyntaxError();
}
int compareType = getCompareType(currentTokenType);
if (compareType < 0) {
break;
......@@ -4333,9 +4338,12 @@ public class Parser {
}
i++;
}
currentToken = StringUtils.cache(sqlCommand.substring(
start, i));
currentTokenType = getTokenType(currentToken);
currentTokenType = ParserUtil.getSaveTokenType(sqlCommand, !identifiersToUpper, start, i, false);
if (currentTokenType == IDENTIFIER) {
currentToken = StringUtils.cache(sqlCommand.substring(start, i));
} else {
currentToken = TOKENS[currentTokenType];
}
parseIndex = i;
return;
case CHAR_QUOTED: {
......@@ -4452,8 +4460,7 @@ public class Parser {
}
currentToken = "'";
checkLiterals(true);
currentValue = ValueString.get(StringUtils.cache(result),
database.getMode().treatEmptyStringsAsNull);
currentValue = ValueString.get(result, database.getMode().treatEmptyStringsAsNull);
parseIndex = i;
currentTokenType = VALUE;
return;
......@@ -4466,8 +4473,7 @@ public class Parser {
String result = sqlCommand.substring(begin, i);
currentToken = "'";
checkLiterals(true);
currentValue = ValueString.get(StringUtils.cache(result),
database.getMode().treatEmptyStringsAsNull);
currentValue = ValueString.get(result, database.getMode().treatEmptyStringsAsNull);
parseIndex = i;
currentTokenType = VALUE;
return;
......@@ -4891,18 +4897,6 @@ public class Parser {
throw getSyntaxError();
}
private int getTokenType(String s) {
int len = s.length();
if (len == 0) {
throw getSyntaxError();
}
if (!identifiersToUpper) {
// if not yet converted to uppercase, do it now
s = StringUtils.toUpperEnglish(s);
}
return ParserUtil.getSaveTokenType(s, false);
}
private boolean isKeyword(String s) {
if (!identifiersToUpper) {
// if not yet converted to uppercase, do it now
......@@ -7713,6 +7707,24 @@ public class Parser {
return StringUtils.quoteIdentifier(s);
}
/**
* Add double quotes around an identifier if required and appends it to the
* specified string builder.
*
* @param builder string builder to append to
* @param s the identifier
* @return the specified builder
*/
public static StringBuilder quoteIdentifier(StringBuilder builder, String s) {
if (s == null) {
return builder.append("\"\"");
}
if (ParserUtil.isSimpleIdentifier(s)) {
return builder.append(s);
}
return StringUtils.quoteIdentifier(builder, s);
}
public void setLiteralsChecked(boolean literalsChecked) {
this.literalsChecked = literalsChecked;
}
......
......@@ -405,7 +405,7 @@ public abstract class Prepared {
for (Value v : values) {
buff.appendExceptFirst(", ");
if (v != null) {
buff.append(v.getSQL());
v.getSQL(buff.builder());
}
}
return buff.toString();
......@@ -418,14 +418,9 @@ public abstract class Prepared {
* @return the SQL snippet
*/
protected static String getSQL(Expression[] list) {
StatementBuilder buff = new StatementBuilder();
for (Expression e : list) {
buff.appendExceptFirst(", ");
if (e != null) {
buff.append(e.getSQL());
}
}
return buff.toString();
StringBuilder builder = new StringBuilder();
Expression.writeExpressions(builder, list);
return builder.toString();
}
/**
......
......@@ -74,7 +74,7 @@ public class CreateUser extends DefineCommand {
char[] passwordChars = pwd == null ? new char[0] : pwd.toCharArray();
byte[] userPasswordHash;
String userName = user.getName();
if (userName.length() == 0 && passwordChars.length == 0) {
if (userName.isEmpty() && passwordChars.length == 0) {
userPasswordHash = new byte[0];
} else {
userPasswordHash = SHA256.getKeyPasswordHash(userName, passwordChars);
......
......@@ -20,7 +20,6 @@ import org.h2.result.RowList;
import org.h2.table.PlanItem;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -137,15 +136,15 @@ public class Delete extends Prepared {
@Override
public String getPlanSQL() {
StringBuilder buff = new StringBuilder();
buff.append("DELETE ");
buff.append("FROM ").append(targetTableFilter.getPlanSQL(false));
buff.append("DELETE FROM ");
targetTableFilter.getPlanSQL(buff, false);
if (condition != null) {
buff.append("\nWHERE ").append(StringUtils.unEnclose(
condition.getSQL()));
buff.append("\nWHERE ");
condition.getUnenclosedSQL(buff);
}
if (limitExpr != null) {
buff.append("\nLIMIT (").append(StringUtils.unEnclose(
limitExpr.getSQL())).append(')');
buff.append("\nLIMIT (");
limitExpr.getUnenclosedSQL(buff).append(')');
}
return buff.toString();
}
......
......@@ -303,7 +303,7 @@ public class Insert extends Prepared implements ResultTarget {
if (e == null) {
buff.append("DEFAULT");
} else {
buff.append(e.getSQL());
e.getSQL(buff.builder());
}
}
buff.append(')');
......@@ -421,7 +421,8 @@ public class Insert extends Prepared implements ResultTarget {
for (Column column : duplicateKeyAssignmentMap.keySet()) {
buff.appendExceptFirst(", ");
Expression ex = duplicateKeyAssignmentMap.get(column);
buff.append(column.getSQL()).append('=').append(ex.getSQL());
buff.append(column.getSQL()).append('=');
ex.getSQL(buff.builder());
}
buff.append(" WHERE ");
Index foundIndex = (Index) de.getSource();
......@@ -429,7 +430,7 @@ public class Insert extends Prepared implements ResultTarget {
throw DbException.getUnsupportedException(
"Unable to apply ON DUPLICATE KEY UPDATE, no index found!");
}
buff.append(prepareUpdateCondition(foundIndex, row).getSQL());
prepareUpdateCondition(foundIndex, row).getSQL(buff.builder());
String sql = buff.toString();
Update command = (Update) session.prepare(sql);
command.setUpdateToCurrentValuesReturnsZero(true);
......
......@@ -248,7 +248,7 @@ public class Merge extends Prepared {
if (e == null) {
buff.append("DEFAULT");
} else {
buff.append(e.getSQL());
e.getSQL(buff.builder());
}
}
buff.append(')');
......
......@@ -25,7 +25,6 @@ import org.h2.result.Row;
import org.h2.result.RowImpl;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.Utils;
import org.h2.value.Value;
......@@ -343,10 +342,10 @@ public class MergeUsing extends Prepared {
@Override
public String getPlanSQL() {
StatementBuilder buff = new StatementBuilder("MERGE INTO ");
buff.append(targetTable.getSQL()).append('\n').append("USING ").append(query.getPlanSQL());
StringBuilder builder = new StringBuilder("MERGE INTO ");
builder.append(targetTable.getSQL()).append('\n').append("USING ").append(query.getPlanSQL());
// TODO add aliases and WHEN clauses to make plan SQL more like original SQL
return buff.toString();
return builder.toString();
}
@Override
......
......@@ -228,7 +228,7 @@ public class Replace extends Prepared {
if (e == null) {
buff.append("DEFAULT");
} else {
buff.append(e.getSQL());
e.getSQL(buff.builder());
}
}
buff.append(')');
......
......@@ -392,7 +392,7 @@ public class ScriptCommand extends ScriptBase {
buff.append(table.getSQL()).append('(');
for (Column col : columns) {
buff.appendExceptFirst(", ");
buff.append(Parser.quoteIdentifier(col.getName()));
Parser.quoteIdentifier(buff.builder(), col.getName());
}
buff.append(") VALUES");
if (!simple) {
......@@ -422,10 +422,10 @@ public class ScriptCommand extends ScriptBase {
id = writeLobStream(v);
buff.append("SYSTEM_COMBINE_BLOB(").append(id).append(')');
} else {
buff.append(v.getSQL());
v.getSQL(buff.builder());
}
} else {
buff.append(v.getSQL());
v.getSQL(buff.builder());
}
}
buff.append(')');
......@@ -471,7 +471,7 @@ public class ScriptCommand extends ScriptBase {
if (len <= 0) {
break;
}
buff.append(StringUtils.convertBytesToHex(bytes, len)).append("')");
StringUtils.convertBytesToHex(buff, bytes, len).append("')");
String sql = buff.toString();
add(sql, true);
}
......@@ -490,7 +490,7 @@ public class ScriptCommand extends ScriptBase {
if (len == 0) {
break;
}
buff.append(StringUtils.quoteStringSQL(new String(chars, 0, len))).
StringUtils.quoteStringSQL(buff, new String(chars, 0, len)).
append(", NULL)");
String sql = buff.toString();
add(sql, true);
......
......@@ -1308,7 +1308,8 @@ public class Select extends Query {
// views.
} else {
buff.append("WITH RECURSIVE ")
.append(t.getSchema().getSQL()).append('.').append(Parser.quoteIdentifier(t.getName()))
.append(t.getSchema().getSQL()).append('.');
Parser.quoteIdentifier(buff.builder(), t.getName())
.append('(');
buff.resetCount();
for (Column c : t.getColumns()) {
......@@ -1327,7 +1328,7 @@ public class Select extends Query {
buff.append(" ON(");
for (Expression distinctExpression: distinctExpressions) {
buff.appendExceptFirst(", ");
buff.append(distinctExpression.getSQL());
distinctExpression.getSQL(buff.builder());
}
buff.append(')');
buff.resetCount();
......@@ -1336,7 +1337,7 @@ public class Select extends Query {
for (int i = 0; i < visibleColumnCount; i++) {
buff.appendExceptFirst(",");
buff.append('\n');
buff.append(StringUtils.indent(exprList[i].getSQL(), 4, false));
StringUtils.indent(buff.builder(), exprList[i].getSQL(), 4, false);
}
buff.append("\nFROM ");
TableFilter filter = topTableFilter;
......@@ -1345,7 +1346,7 @@ public class Select extends Query {
int i = 0;
do {
buff.appendExceptFirst("\n");
buff.append(filter.getPlanSQL(i++ > 0));
filter.getPlanSQL(buff.builder(), i++ > 0);
filter = filter.getJoin();
} while (filter != null);
} else {
......@@ -1354,14 +1355,14 @@ public class Select extends Query {
for (TableFilter f : topFilters) {
do {
buff.appendExceptFirst("\n");
buff.append(f.getPlanSQL(i++ > 0));
f.getPlanSQL(buff.builder(), i++ > 0);
f = f.getJoin();
} while (f != null);
}
}
if (condition != null) {
buff.append("\nWHERE ").append(
StringUtils.unEnclose(condition.getSQL()));
buff.append("\nWHERE ");
condition.getUnenclosedSQL(buff.builder());
}
if (groupIndex != null) {
buff.append("\nGROUP BY ");
......@@ -1370,7 +1371,7 @@ public class Select extends Query {
Expression g = exprList[gi];
g = g.getNonAliasExpression();
buff.appendExceptFirst(", ");
buff.append(StringUtils.unEnclose(g.getSQL()));
g.getUnenclosedSQL(buff.builder());
}
}
if (group != null) {
......@@ -1378,7 +1379,7 @@ public class Select extends Query {
buff.resetCount();
for (Expression g : group) {
buff.appendExceptFirst(", ");
buff.append(StringUtils.unEnclose(g.getSQL()));
g.getUnenclosedSQL(buff.builder());
}
}
if (having != null) {
......@@ -1386,12 +1387,12 @@ public class Select extends Query {
// in this case the query is not run directly, just getPlanSQL is
// called
Expression h = having;
buff.append("\nHAVING ").append(
StringUtils.unEnclose(h.getSQL()));
buff.append("\nHAVING ");
h.getUnenclosedSQL(buff.builder());
} else if (havingIndex >= 0) {
Expression h = exprList[havingIndex];
buff.append("\nHAVING ").append(
StringUtils.unEnclose(h.getSQL()));
buff.append("\nHAVING ");
h.getUnenclosedSQL(buff.builder());
}
if (sort != null) {
buff.append("\nORDER BY ").append(
......@@ -1407,8 +1408,8 @@ public class Select extends Query {
}
appendLimitToSQL(buff.builder());
if (sampleSizeExpr != null) {
buff.append("\nSAMPLE_SIZE ").append(
StringUtils.unEnclose(sampleSizeExpr.getSQL()));
buff.append("\nSAMPLE_SIZE ");
sampleSizeExpr.getUnenclosedSQL(buff.builder());
}
if (isForUpdate) {
buff.append("\nFOR UPDATE");
......
......@@ -33,9 +33,10 @@ public class SelectOrderBy {
public String getSQL() {
StringBuilder buff = new StringBuilder();
if (expression != null) {
buff.append('=').append(expression.getSQL());
buff.append('=');
expression.getSQL(buff);
} else {
buff.append(columnIndexExpr.getSQL());
columnIndexExpr.getSQL(buff);
}
SortOrder.typeToString(buff, sortType);
return buff.toString();
......
......@@ -28,7 +28,6 @@ import org.h2.table.ColumnResolver;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.ColumnNamer;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueInt;
import org.h2.value.ValueNull;
......@@ -429,8 +428,8 @@ public class SelectUnion extends Query {
}
appendLimitToSQL(buff);
if (sampleSizeExpr != null) {
buff.append("\nSAMPLE_SIZE ").append(
StringUtils.unEnclose(sampleSizeExpr.getSQL()));
buff.append("\nSAMPLE_SIZE ");
sampleSizeExpr.getUnenclosedSQL(buff);
}
if (isForUpdate) {
buff.append("\nFOR UPDATE");
......
......@@ -27,8 +27,6 @@ import org.h2.table.Column;
import org.h2.table.PlanItem;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -217,21 +215,25 @@ public class Update extends Prepared {
@Override
public String getPlanSQL() {
StatementBuilder buff = new StatementBuilder("UPDATE ");
buff.append(targetTableFilter.getPlanSQL(false)).append("\nSET\n ");
for (Column c : columns) {
Expression e = expressionMap.get(c);
buff.appendExceptFirst(",\n ");
buff.append(c.getName()).append(" = ").append(e.getSQL());
StringBuilder builder = new StringBuilder("UPDATE ");
targetTableFilter.getPlanSQL(builder, false).append("\nSET\n ");
for (int i = 0, size = columns.size(); i < size; i++) {
if (i > 0) {
builder.append(",\n ");
}
Column c = columns.get(i);
builder.append(c.getName()).append(" = ");
expressionMap.get(c).getSQL(builder);
}
if (condition != null) {
buff.append("\nWHERE ").append(StringUtils.unEnclose(condition.getSQL()));
builder.append("\nWHERE ");
condition.getUnenclosedSQL(builder);
}
if (limitExpr != null) {
buff.append("\nLIMIT ").append(
StringUtils.unEnclose(limitExpr.getSQL()));
builder.append("\nLIMIT ");
limitExpr.getUnenclosedSQL(builder);
}
return buff.toString();
return builder.toString();
}
@Override
......
......@@ -56,15 +56,18 @@ public class ConstraintCheck extends Constraint {
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff, comment);
}
buff.append(" CHECK").append(StringUtils.enclose(expr.getSQL()))
.append(" NOCHECK");
buff.append(" CHECK(");
expr.getUnenclosedSQL(buff).append(") NOCHECK");
return buff.toString();
}
private String getShortDescription() {
return getName() + ": " + expr.getSQL();
StringBuilder builder = new StringBuilder().append(getName()).append(": ");
expr.getSQL(builder);
return builder.toString();
}
@Override
......@@ -140,8 +143,11 @@ public class ConstraintCheck extends Constraint {
// don't check at startup
return;
}
String sql = "SELECT 1 FROM " + filter.getTable().getSQL() +
" WHERE NOT(" + expr.getSQL() + ")";
StringBuilder builder = new StringBuilder().append("SELECT 1 FROM ")
.append(filter.getTable().getSQL())
.append(" WHERE NOT(");
expr.getSQL(builder).append(')');
String sql = builder.toString();
ResultInterface r = session.prepare(sql).query(1);
if (r.next()) {
throw DbException.get(ErrorCode.CHECK_CONSTRAINT_VIOLATED_1, getName());
......
......@@ -87,7 +87,8 @@ public class ConstraintReferential extends Constraint {
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff.builder(), comment);
}
IndexColumn[] cols = columns;
IndexColumn[] refCols = refColumns;
......@@ -566,8 +567,8 @@ public class ConstraintReferential extends Constraint {
buff.append("UPDATE ").append(table.getSQL()).append(" SET ");
buff.resetCount();
for (IndexColumn c : columns) {
buff.appendExceptFirst(" , ");
buff.append(Parser.quoteIdentifier(c.column.getName())).append("=?");
buff.appendExceptFirst(", ");
Parser.quoteIdentifier(buff.builder(), c.column.getName()).append("=?");
}
}
......@@ -576,7 +577,7 @@ public class ConstraintReferential extends Constraint {
buff.resetCount();
for (IndexColumn c : columns) {
buff.appendExceptFirst(" AND ");
buff.append(Parser.quoteIdentifier(c.column.getName())).append("=?");
Parser.quoteIdentifier(buff.builder(), c.column.getName()).append("=?");
}
}
......
......@@ -52,12 +52,13 @@ public class ConstraintUnique extends Constraint {
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff.builder(), comment);
}
buff.append(' ').append(getConstraintType().getSqlName()).append('(');
for (IndexColumn c : columns) {
buff.appendExceptFirst(", ");
buff.append(Parser.quoteIdentifier(c.column.getName()));
Parser.quoteIdentifier(buff.builder(), c.column.getName());
}
buff.append(')');
if (internalIndex && indexOwner && forTable == this.table) {
......
......@@ -74,7 +74,7 @@ public class Comment extends DbObjectBase {
if (commentText == null) {
buff.append("NULL");
} else {
buff.append(StringUtils.quoteStringSQL(commentText));
StringUtils.quoteStringSQL(buff, commentText);
}
return buff.toString();
}
......
......@@ -252,7 +252,7 @@ public class ConnectionInfo implements Cloneable {
url = url.substring(0, idx);
String[] list = StringUtils.arraySplit(settings, ';', false);
for (String setting : list) {
if (setting.length() == 0) {
if (setting.isEmpty()) {
continue;
}
int equal = setting.indexOf('=');
......@@ -326,7 +326,7 @@ public class ConnectionInfo implements Cloneable {
if (passwordHash) {
return StringUtils.convertHexToBytes(new String(password));
}
if (userName.length() == 0 && password.length == 0) {
if (userName.isEmpty() && password.length == 0) {
return new byte[0];
}
return SHA256.getKeyPasswordHash(userName, password);
......@@ -643,7 +643,7 @@ public class ConnectionInfo implements Cloneable {
private static String remapURL(String url) {
String urlMap = SysProperties.URL_MAP;
if (urlMap != null && urlMap.length() > 0) {
if (urlMap != null && !urlMap.isEmpty()) {
try {
SortedProperties prop;
prop = SortedProperties.loadProperties(urlMap);
......@@ -653,7 +653,7 @@ public class ConnectionInfo implements Cloneable {
prop.store(urlMap);
} else {
url2 = url2.trim();
if (url2.length() > 0) {
if (!url2.isEmpty()) {
return url2;
}
}
......
......@@ -642,7 +642,7 @@ public class Database implements DataHandler {
n = tokenizer.nextToken();
}
}
if (n == null || n.length() == 0) {
if (n == null || n.isEmpty()) {
n = "unnamed";
}
return dbSettings.databaseToUpper ? StringUtils.toUpperEnglish(n) : n;
......@@ -2274,7 +2274,7 @@ public class Database implements DataHandler {
}
public void setEventListenerClass(String className) {
if (className == null || className.length() == 0) {
if (className == null || className.isEmpty()) {
eventListener = null;
} else {
try {
......
......@@ -223,10 +223,11 @@ public class FunctionAlias extends SchemaObjectBase {
buff.append(" NOBUFFER");
}
if (source != null) {
buff.append(" AS ").append(StringUtils.quoteStringSQL(source));
buff.append(" AS ");
StringUtils.quoteStringSQL(buff, source);
} else {
buff.append(" FOR ").append(Parser.quoteIdentifier(
className + "." + methodName));
buff.append(" FOR ");
Parser.quoteIdentifier(buff, className + "." + methodName);
}
return buff.toString();
}
......
......@@ -159,13 +159,14 @@ public class User extends RightOwner {
StringBuilder buff = new StringBuilder("CREATE USER IF NOT EXISTS ");
buff.append(getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff, comment);
}
if (password) {
buff.append(" SALT '").
append(StringUtils.convertBytesToHex(salt)).
append("' HASH '").
append(StringUtils.convertBytesToHex(passwordHash)).
buff.append(" SALT '");
StringUtils.convertBytesToHex(buff, salt).
append("' HASH '");
StringUtils.convertBytesToHex(buff, passwordHash).
append('\'');
} else {
buff.append(" PASSWORD ''");
......
......@@ -78,8 +78,9 @@ public class Alias extends Expression {
}
@Override
public String getSQL() {
return expr.getSQL() + " AS " + Parser.quoteIdentifier(alias);
public StringBuilder getSQL(StringBuilder builder) {
expr.getSQL(builder).append(" AS ");
return Parser.quoteIdentifier(builder, alias);
}
@Override
......
......@@ -68,10 +68,12 @@ public class BinaryOperation extends Expression {
}
@Override
public String getSQL() {
public StringBuilder getSQL(StringBuilder builder) {
// don't remove the space, otherwise it might end up some thing like
// --1 which is a line remark
return '(' + left.getSQL() + ' ' + getOperationToken() + ' ' + right.getSQL() + ')';
builder.append('(');
left.getSQL(builder).append(' ').append(getOperationToken()).append(' ');
return right.getSQL(builder).append(')');
}
private String getOperationToken() {
......
......@@ -72,21 +72,24 @@ public class CompareLike extends Condition {
}
private static Character getEscapeChar(String s) {
return s == null || s.length() == 0 ? null : s.charAt(0);
return s == null || s.isEmpty() ? null : s.charAt(0);
}
@Override
public String getSQL() {
String sql;
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
if (regexp) {
sql = left.getSQL() + " REGEXP " + right.getSQL();
left.getSQL(builder).append(" REGEXP ");
right.getSQL(builder);
} else {
sql = left.getSQL() + " LIKE " + right.getSQL();
left.getSQL(builder).append(" LIKE ");
right.getSQL(builder);
if (escape != null) {
sql += " ESCAPE " + escape.getSQL();
builder.append(" ESCAPE ");
escape.getSQL(builder);
}
}
return "(" + sql + ")";
return builder.append(')');
}
@Override
......
......@@ -126,23 +126,25 @@ public class Comparison extends Condition {
}
@Override
public String getSQL() {
String sql;
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
switch (compareType) {
case IS_NULL:
sql = left.getSQL() + " IS NULL";
left.getSQL(builder).append(" IS NULL");
break;
case IS_NOT_NULL:
sql = left.getSQL() + " IS NOT NULL";
left.getSQL(builder).append(" IS NOT NULL");
break;
case SPATIAL_INTERSECTS:
sql = "INTERSECTS(" + left.getSQL() + ", " + right.getSQL() + ")";
builder.append("INTERSECTS(");
left.getSQL(builder).append(", ");
right.getSQL(builder).append(')');
break;
default:
sql = left.getSQL() + " " + getCompareOperator(compareType) +
" " + right.getSQL();
left.getSQL(builder).append(' ').append(getCompareOperator(compareType)).append(' ');
right.getSQL(builder);
}
return "(" + sql + ")";
return builder.append(')');
}
/**
......
......@@ -42,19 +42,20 @@ public class ConditionAndOr extends Condition {
}
@Override
public String getSQL() {
String sql;
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder);
switch (andOrType) {
case AND:
sql = left.getSQL() + "\n AND " + right.getSQL();
builder.append("\n AND ");
break;
case OR:
sql = left.getSQL() + "\n OR " + right.getSQL();
builder.append("\n OR ");
break;
default:
throw DbException.throwInternalError("andOrType=" + andOrType);
}
return "(" + sql + ")";
return right.getSQL(builder).append(')');
}
@Override
......
......@@ -41,8 +41,9 @@ public class ConditionExists extends Condition {
}
@Override
public String getSQL() {
return "EXISTS(\n" + StringUtils.indent(query.getPlanSQL(), 4, false) + ")";
public StringBuilder getSQL(StringBuilder builder) {
builder.append("EXISTS(\n");
return StringUtils.indent(builder, query.getPlanSQL(), 4, false).append(')');
}
@Override
......
......@@ -11,7 +11,6 @@ import org.h2.engine.Session;
import org.h2.index.IndexCondition;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
import org.h2.value.ValueNull;
......@@ -152,14 +151,11 @@ public class ConditionIn extends Condition {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder("(");
buff.append(left.getSQL()).append(" IN(");
for (Expression e : valueList) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
return buff.append("))").toString();
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(" IN(");
writeExpressions(builder, valueList);
return builder.append("))");
}
@Override
......
......@@ -15,7 +15,6 @@ import org.h2.index.IndexCondition;
import org.h2.message.DbException;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.value.ExtTypeInfo;
import org.h2.value.Value;
import org.h2.value.ValueBoolean;
......@@ -114,14 +113,11 @@ public class ConditionInConstantSet extends Condition {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder("(");
buff.append(left.getSQL()).append(" IN(");
for (Expression e : valueList) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
return buff.append("))").toString();
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(" IN(");
writeExpressions(builder, valueList);
return builder.append("))");
}
@Override
......
......@@ -140,8 +140,10 @@ public class ConditionInParameter extends Condition {
}
@Override
public String getSQL() {
return '(' + left.getSQL() + " = ANY(" + parameter.getSQL() + "))";
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(" = ANY(");
return parameter.getSQL(builder).append("))");
}
@Override
......
......@@ -129,23 +129,22 @@ public class ConditionInSelect extends Condition {
}
@Override
public String getSQL() {
StringBuilder buff = new StringBuilder();
buff.append('(').append(left.getSQL()).append(' ');
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(' ');
if (all) {
buff.append(Comparison.getCompareOperator(compareType)).
builder.append(Comparison.getCompareOperator(compareType)).
append(" ALL");
} else {
if (compareType == Comparison.EQUAL) {
buff.append("IN");
builder.append("IN");
} else {
buff.append(Comparison.getCompareOperator(compareType)).
builder.append(Comparison.getCompareOperator(compareType)).
append(" ANY");
}
}
buff.append("(\n").append(StringUtils.indent(query.getPlanSQL(), 4, false)).
append("))");
return buff.toString();
builder.append("(\n");
return StringUtils.indent(builder, query.getPlanSQL(), 4, false).append("))");
}
@Override
......
......@@ -65,8 +65,9 @@ public class ConditionNot extends Condition {
}
@Override
public String getSQL() {
return "(NOT " + condition.getSQL() + ")";
public StringBuilder getSQL(StringBuilder builder) {
builder.append("(NOT ");
return condition.getSQL(builder).append(')');
}
@Override
......
......@@ -5,13 +5,14 @@
*/
package org.h2.expression;
import java.util.List;
import org.h2.engine.Database;
import org.h2.engine.Session;
import org.h2.result.ResultInterface;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -39,6 +40,24 @@ public abstract class Expression {
private boolean addedToFilter;
public static void writeExpressions(StringBuilder builder, List<? extends Expression> expressions) {
for (int i = 0, length = expressions.size(); i < length; i++) {
if (i > 0) {
builder.append(", ");
}
expressions.get(i).getSQL(builder);
}
}
public static void writeExpressions(StringBuilder builder, Expression[] expressions) {
for (int i = 0, length = expressions.length; i < length; i++) {
if (i > 0) {
builder.append(", ");
}
expressions[i].getSQL(builder);
}
}
/**
* Return the resulting value for the current row.
*
......@@ -110,7 +129,39 @@ public abstract class Expression {
*
* @return the SQL statement
*/
public abstract String getSQL();
public String getSQL() {
return getSQL(new StringBuilder()).toString();
}
/**
* Appends the SQL statement of this expression to the specified builder.
* This may not always be the original SQL statement, specially after
* optimization.
*
* @param builder
* string builder
* @return the specified string builder
*/
public abstract StringBuilder getSQL(StringBuilder builder);
/**
* Appends the SQL statement of this expression to the specified builder.
* This may not always be the original SQL statement, specially after
* optimization. Enclosing '(' and ')' are removed.
*
* @param builder
* string builder
* @return the specified string builder
*/
public StringBuilder getUnenclosedSQL(StringBuilder builder) {
int first = builder.length();
int last = getSQL(builder).length() - 1;
if (last > first && builder.charAt(first) == '(' && builder.charAt(last) == ')') {
builder.setLength(last);
builder.deleteCharAt(first);
}
return builder;
}
/**
* Update an aggregate value. This method is called at statement execution
......@@ -268,7 +319,7 @@ public abstract class Expression {
* @return the alias name
*/
public String getAlias() {
return StringUtils.unEnclose(getSQL());
return getUnenclosedSQL(new StringBuilder()).toString();
}
/**
......
......@@ -55,23 +55,32 @@ public class ExpressionColumn extends Expression {
}
@Override
public String getSQL() {
String sql;
public StringBuilder getSQL(StringBuilder builder) {
boolean quote = database.getSettings().databaseToUpper;
if (column != null) {
sql = column.getSQL();
} else {
sql = quote ? Parser.quoteIdentifier(columnName) : columnName;
if (schemaName != null) {
if (quote) {
Parser.quoteIdentifier(builder, schemaName);
} else {
builder.append(schemaName);
}
builder.append('.');
}
if (tableAlias != null) {
String a = quote ? Parser.quoteIdentifier(tableAlias) : tableAlias;
sql = a + "." + sql;
if (quote) {
Parser.quoteIdentifier(builder, tableAlias);
} else {
builder.append(tableAlias);
}
builder.append('.');
}
if (schemaName != null) {
String s = quote ? Parser.quoteIdentifier(schemaName) : schemaName;
sql = s + "." + sql;
if (column != null) {
builder.append(column.getSQL());
} else if (quote) {
Parser.quoteIdentifier(builder, columnName);
} else {
builder.append(columnName);
}
return sql;
return builder;
}
public TableFilter getTableFilter() {
......
......@@ -9,7 +9,6 @@ import org.h2.engine.Session;
import org.h2.table.Column;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -85,16 +84,13 @@ public class ExpressionList extends Expression {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder("(");
for (Expression e: list) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
writeExpressions(builder, list);
if (list.length == 1) {
buff.append(',');
builder.append(',');
}
return buff.append(')').toString();
return builder.append(')');
}
@Override
......
......@@ -50,7 +50,6 @@ import org.h2.util.DateTimeUtils;
import org.h2.util.IOUtils;
import org.h2.util.JdbcUtils;
import org.h2.util.MathUtils;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.ToChar;
import org.h2.util.ToDateParser;
......@@ -682,7 +681,7 @@ public class Function extends Expression implements FunctionCall {
// string
case ASCII: {
String s = v0.getString();
if (s.length() == 0) {
if (s.isEmpty()) {
result = ValueNull.INSTANCE;
} else {
result = ValueInt.get(s.charAt(0));
......@@ -2582,36 +2581,41 @@ public class Function extends Expression implements FunctionCall {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(info.name);
public StringBuilder getSQL(StringBuilder builder) {
builder.append(info.name);
if (info.type == CASE) {
if (args[0] != null) {
buff.append(' ').append(args[0].getSQL());
builder.append(' ');
args[0].getSQL(builder);
}
for (int i = 1, len = args.length - 1; i < len; i += 2) {
buff.append(" WHEN ").append(args[i].getSQL());
buff.append(" THEN ").append(args[i + 1].getSQL());
builder.append(" WHEN ");
args[i].getSQL(builder);
builder.append(" THEN ");
args[i + 1].getSQL(builder);
}
if (args.length % 2 == 0) {
buff.append(" ELSE ").append(args[args.length - 1].getSQL());
builder.append(" ELSE ");
args[args.length - 1].getSQL(builder);
}
return buff.append(" END").toString();
return builder.append(" END");
}
buff.append('(');
builder.append('(');
switch (info.type) {
case CAST: {
buff.append(args[0].getSQL()).append(" AS ").
args[0].getSQL(builder).append(" AS ").
append(new Column(null, dataType, precision,
scale, displaySize, extTypeInfo).getCreateSQL());
break;
}
case CONVERT: {
if (database.getMode().swapConvertFunctionParameters) {
buff.append(new Column(null, dataType, precision,
builder.append(new Column(null, dataType, precision,
scale, displaySize).getCreateSQL()).
append(',').append(args[0].getSQL());
append(',');
args[0].getSQL(builder);
} else {
buff.append(args[0].getSQL()).append(',').
args[0].getSQL(builder).append(',').
append(new Column(null, dataType, precision,
scale, displaySize).getCreateSQL());
}
......@@ -2619,17 +2623,14 @@ public class Function extends Expression implements FunctionCall {
}
case EXTRACT: {
ValueString v = (ValueString) ((ValueExpression) args[0]).getValue(null);
buff.append(v.getString()).append(" FROM ").append(args[1].getSQL());
builder.append(v.getString()).append(" FROM ");
args[1].getSQL(builder);
break;
}
default: {
for (Expression e : args) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
}
default:
writeExpressions(builder, args);
}
return buff.append(')').toString();
return builder.append(')');
}
@Override
......@@ -2703,19 +2704,17 @@ public class Function extends Expression implements FunctionCall {
String fieldDelimiter, String escapeCharacter) {
if (fieldSeparator != null) {
csv.setFieldSeparatorWrite(fieldSeparator);
if (fieldSeparator.length() > 0) {
if (!fieldSeparator.isEmpty()) {
char fs = fieldSeparator.charAt(0);
csv.setFieldSeparatorRead(fs);
}
}
if (fieldDelimiter != null) {
char fd = fieldDelimiter.length() == 0 ?
0 : fieldDelimiter.charAt(0);
char fd = fieldDelimiter.isEmpty() ? 0 : fieldDelimiter.charAt(0);
csv.setFieldDelimiter(fd);
}
if (escapeCharacter != null) {
char ec = escapeCharacter.length() == 0 ?
0 : escapeCharacter.charAt(0);
char ec = escapeCharacter.isEmpty() ? 0 : escapeCharacter.charAt(0);
csv.setEscapeCharacter(ec);
}
}
......
......@@ -113,8 +113,10 @@ public class IntervalOperation extends Expression {
}
@Override
public String getSQL() {
return '(' + left.getSQL() + ' ' + getOperationToken() + ' ' + right.getSQL() + ')';
public StringBuilder getSQL(StringBuilder builder) {
builder.append('(');
left.getSQL(builder).append(' ').append(getOperationToken()).append(' ');
return right.getSQL(builder).append(')');
}
private char getOperationToken() {
......
......@@ -11,7 +11,6 @@ import org.h2.engine.FunctionAlias;
import org.h2.engine.Session;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -89,21 +88,15 @@ public class JavaFunction extends Expression implements FunctionCall {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder();
public StringBuilder getSQL(StringBuilder builder) {
// TODO always append the schema once FUNCTIONS_IN_SCHEMA is enabled
if (functionAlias.getDatabase().getSettings().functionsInSchema ||
!functionAlias.getSchema().getName().equals(Constants.SCHEMA_MAIN)) {
buff.append(
Parser.quoteIdentifier(functionAlias.getSchema().getName()))
.append('.');
Parser.quoteIdentifier(builder, functionAlias.getSchema().getName()).append('.');
}
buff.append(Parser.quoteIdentifier(functionAlias.getName())).append('(');
for (Expression e : args) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
return buff.append(')').toString();
Parser.quoteIdentifier(builder, functionAlias.getName()).append('(');
writeExpressions(builder, this.args);
return builder.append(')');
}
@Override
......
......@@ -30,8 +30,8 @@ public class Parameter extends Expression implements ParameterInterface {
}
@Override
public String getSQL() {
return "?" + (index + 1);
public StringBuilder getSQL(StringBuilder builder) {
return builder.append('?').append(index + 1);
}
@Override
......
......@@ -72,6 +72,11 @@ public class Rownum extends Expression {
return "ROWNUM()";
}
@Override
public StringBuilder getSQL(StringBuilder builder) {
return builder.append("ROWNUM()");
}
@Override
public void updateAggregate(Session session, int stage) {
// nothing to do
......
......@@ -67,8 +67,9 @@ public class SequenceValue extends Expression {
}
@Override
public String getSQL() {
return "(NEXT VALUE FOR " + sequence.getSQL() +")";
public StringBuilder getSQL(StringBuilder builder) {
builder.append("(NEXT VALUE FOR ");
return builder.append(sequence.getSQL()).append(')');
}
@Override
......
......@@ -89,8 +89,8 @@ public class Subquery extends Expression {
}
@Override
public String getSQL() {
return "(" + query.getPlanSQL() + ")";
public StringBuilder getSQL(StringBuilder builder) {
return builder.append('(').append(query.getPlanSQL()).append(')');
}
@Override
......
......@@ -13,7 +13,6 @@ import org.h2.engine.Session;
import org.h2.message.DbException;
import org.h2.result.LocalResult;
import org.h2.table.Column;
import org.h2.util.StatementBuilder;
import org.h2.value.Value;
import org.h2.value.ValueArray;
import org.h2.value.ValueNull;
......@@ -46,15 +45,16 @@ public class TableFunction extends Function {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder(getName());
buff.append('(');
int i = 0;
for (Expression e : args) {
buff.appendExceptFirst(", ");
buff.append(columnList[i++].getCreateSQL()).append('=').append(e.getSQL());
public StringBuilder getSQL(StringBuilder builder) {
builder.append(getName()).append('(');
for (int i = 0; i < args.length; i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(columnList[i].getCreateSQL()).append('=');
args[i].getSQL(builder);
}
return buff.append(')').toString();
return builder.append(')');
}
......
......@@ -24,10 +24,11 @@ public class UnaryOperation extends Expression {
}
@Override
public String getSQL() {
public StringBuilder getSQL(StringBuilder builder) {
// don't remove the space, otherwise it might end up some thing like
// --1 which is a line remark
return "(- " + arg.getSQL() + ')';
builder.append("(- ");
return arg.getSQL(builder).append(')');
}
@Override
......
......@@ -135,11 +135,13 @@ public class ValueExpression extends Expression {
}
@Override
public String getSQL() {
public StringBuilder getSQL(StringBuilder builder) {
if (this == DEFAULT) {
return "DEFAULT";
builder.append("DEFAULT");
} else {
value.getSQL(builder);
}
return value.getSQL();
return builder;
}
@Override
......
......@@ -41,8 +41,9 @@ public class Variable extends Expression {
}
@Override
public String getSQL() {
return "@" + Parser.quoteIdentifier(name);
public StringBuilder getSQL(StringBuilder builder) {
builder.append('@');
return Parser.quoteIdentifier(builder, name);
}
@Override
......
......@@ -116,24 +116,17 @@ public class Wildcard extends Expression {
}
@Override
public String getSQL() {
StringBuilder builder = new StringBuilder();
public StringBuilder getSQL(StringBuilder builder) {
if (table != null) {
builder.append(StringUtils.quoteIdentifier(table)).append('.');
StringUtils.quoteIdentifier(builder, table).append('.');
}
builder.append('*');
if (exceptColumns != null) {
builder.append(" EXCEPT (");
for (int i = 0; i < exceptColumns.size(); i++) {
if (i > 0) {
builder.append(", ");
}
ExpressionColumn ec = exceptColumns.get(i);
builder.append(ec.getSQL());
}
writeExpressions(builder, exceptColumns);
builder.append(')');
}
return builder.toString();
return builder;
}
@Override
......
......@@ -159,7 +159,8 @@ public abstract class AbstractAggregate extends DataAnalysisOperation {
@Override
protected StringBuilder appendTailConditions(StringBuilder builder) {
if (filterCondition != null) {
builder.append(" FILTER (WHERE ").append(filterCondition.getSQL()).append(')');
builder.append(" FILTER (WHERE ");
filterCondition.getSQL(builder).append(')');
}
return super.appendTailConditions(builder);
}
......
......@@ -30,7 +30,6 @@ import org.h2.table.ColumnResolver;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.ValueHashMap;
import org.h2.value.CompareMode;
import org.h2.value.DataType;
......@@ -729,39 +728,40 @@ public class Aggregate extends AbstractAggregate {
return displaySize;
}
private String getSQLGroupConcat() {
StringBuilder buff = new StringBuilder("GROUP_CONCAT(");
private StringBuilder getSQLGroupConcat(StringBuilder builder) {
builder.append("GROUP_CONCAT(");
if (distinct) {
buff.append("DISTINCT ");
builder.append("DISTINCT ");
}
buff.append(on.getSQL());
Window.appendOrderBy(buff, orderByList);
on.getSQL(builder);
Window.appendOrderBy(builder, orderByList);
if (groupConcatSeparator != null) {
buff.append(" SEPARATOR ").append(groupConcatSeparator.getSQL());
builder.append(" SEPARATOR ");
groupConcatSeparator.getSQL(builder);
}
buff.append(')');
return appendTailConditions(buff).toString();
builder.append(')');
return appendTailConditions(builder);
}
private String getSQLArrayAggregate() {
StringBuilder buff = new StringBuilder("ARRAY_AGG(");
private StringBuilder getSQLArrayAggregate(StringBuilder builder) {
builder.append("ARRAY_AGG(");
if (distinct) {
buff.append("DISTINCT ");
builder.append("DISTINCT ");
}
buff.append(on.getSQL());
Window.appendOrderBy(buff, orderByList);
buff.append(')');
return appendTailConditions(buff).toString();
on.getSQL(builder);
Window.appendOrderBy(builder, orderByList);
builder.append(')');
return appendTailConditions(builder);
}
@Override
public String getSQL() {
public StringBuilder getSQL(StringBuilder builder) {
String text;
switch (type) {
case GROUP_CONCAT:
return getSQLGroupConcat();
return getSQLGroupConcat(builder);
case COUNT_ALL:
return appendTailConditions(new StringBuilder().append("COUNT(*)")).toString();
return appendTailConditions(builder.append("COUNT(*)"));
case COUNT:
text = "COUNT";
break;
......@@ -811,7 +811,7 @@ public class Aggregate extends AbstractAggregate {
text = "MEDIAN";
break;
case ARRAY_AGG:
return getSQLArrayAggregate();
return getSQLArrayAggregate(builder);
case MODE:
text = "MODE";
break;
......@@ -821,13 +821,15 @@ public class Aggregate extends AbstractAggregate {
default:
throw DbException.throwInternalError("type=" + type);
}
StringBuilder builder = new StringBuilder().append(text);
builder.append(text);
if (distinct) {
builder.append("(DISTINCT ").append(on.getSQL()).append(')');
builder.append("(DISTINCT ");
on.getSQL(builder).append(')');
} else {
builder.append(StringUtils.enclose(on.getSQL()));
builder.append('(');
on.getUnenclosedSQL(builder).append(')');
}
return appendTailConditions(builder).toString();
return appendTailConditions(builder);
}
private Index getMinMaxColumnIndex() {
......
......@@ -351,7 +351,8 @@ public abstract class DataAnalysisOperation extends Expression {
protected StringBuilder appendTailConditions(StringBuilder builder) {
if (over != null) {
builder.append(' ').append(over.getSQL());
builder.append(' ');
over.getSQL(builder);
}
return builder;
}
......
......@@ -17,7 +17,6 @@ import org.h2.expression.ExpressionVisitor;
import org.h2.message.DbException;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.value.DataType;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -68,15 +67,11 @@ public class JavaAggregate extends AbstractAggregate {
}
@Override
public String getSQL() {
StatementBuilder buff = new StatementBuilder();
buff.append(Parser.quoteIdentifier(userAggregate.getName())).append('(');
for (Expression e : args) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
buff.append(')');
return appendTailConditions(buff.builder()).toString();
public StringBuilder getSQL(StringBuilder builder) {
Parser.quoteIdentifier(builder, userAggregate.getName()).append('(');
writeExpressions(builder, args);
builder.append(')');
return appendTailConditions(builder);
}
@Override
......
......@@ -15,7 +15,6 @@ import org.h2.message.DbException;
import org.h2.result.SortOrder;
import org.h2.table.ColumnResolver;
import org.h2.table.TableFilter;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueArray;
......@@ -49,7 +48,7 @@ public final class Window {
if (i > 0) {
builder.append(", ");
}
builder.append(o.expression.getSQL());
o.expression.getSQL(builder);
SortOrder.typeToString(builder, o.sortType);
}
}
......@@ -204,23 +203,22 @@ public final class Window {
}
/**
* Returns SQL representation.
* Appends SQL representation to the specified builder.
*
* @return SQL representation.
* @see Expression#getSQL()
* @param builder
* string builder
* @return the specified string builder
* @see Expression#getSQL(StringBuilder)
*/
public String getSQL() {
if (partitionBy == null && orderBy == null && frame == null) {
return "OVER ()";
}
StringBuilder builder = new StringBuilder().append("OVER (");
public StringBuilder getSQL(StringBuilder builder) {
builder.append("OVER (");
if (partitionBy != null) {
builder.append("PARTITION BY ");
for (int i = 0; i < partitionBy.size(); i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(StringUtils.unEnclose(partitionBy.get(i).getSQL()));
partitionBy.get(i).getUnenclosedSQL(builder);
}
}
appendOrderBy(builder, orderBy);
......@@ -228,9 +226,9 @@ public final class Window {
if (builder.charAt(builder.length() - 1) != '(') {
builder.append(' ');
}
builder.append(frame.getSQL());
frame.getSQL(builder);
}
return builder.append(')').toString();
return builder.append(')');
}
/**
......@@ -257,7 +255,7 @@ public final class Window {
@Override
public String toString() {
return getSQL();
return getSQL(new StringBuilder()).toString();
}
}
......@@ -584,23 +584,27 @@ public final class WindowFrame {
}
/**
* Returns SQL representation.
* Append SQL representation to the specified builder.
*
* @return SQL representation.
* @see org.h2.expression.Expression#getSQL()
* @param builder
* string builder
* @return the specified string builder
* @see org.h2.expression.Expression#getSQL(StringBuilder)
*/
public String getSQL() {
StringBuilder builder = new StringBuilder();
public StringBuilder getSQL(StringBuilder builder) {
builder.append(units.getSQL());
if (following == null) {
builder.append(' ').append(starting.getSQL(false));
builder.append(' ');
starting.getSQL(builder, false);
} else {
builder.append(" BETWEEN ").append(starting.getSQL(false)).append(" AND ").append(following.getSQL(true));
builder.append(" BETWEEN ");
starting.getSQL(builder, false).append(" AND ");
following.getSQL(builder, true);
}
if (exclusion != WindowFrameExclusion.EXCLUDE_NO_OTHERS) {
builder.append(' ').append(exclusion.getSQL());
}
return builder.toString();
return builder;
}
}
......@@ -52,19 +52,21 @@ public class WindowFrameBound {
}
/**
* Returns SQL representation.
* Appends SQL representation to the specified builder.
*
* @param builder
* string builder
* @param following
* if false return SQL for starting clause, if true return SQL
* for following clause
* @return SQL representation.
* @see Expression#getSQL()
* @return the specified string builder
* @see Expression#getSQL(StringBuilder)
*/
public String getSQL(boolean following) {
public StringBuilder getSQL(StringBuilder builder, boolean following) {
if (type == WindowFrameBoundType.PRECEDING || type == WindowFrameBoundType.FOLLOWING) {
return value.getSQL() + ' ' + type.getSQL();
value.getSQL(builder).append(' ');
}
return type.getSQL();
return builder.append(type.getSQL());
}
}
......@@ -515,16 +515,11 @@ public class WindowFunction extends DataAnalysisOperation {
}
@Override
public String getSQL() {
public StringBuilder getSQL(StringBuilder builder) {
String name = type.getSQL();
StringBuilder builder = new StringBuilder().append(name).append('(');
builder.append(name).append('(');
if (args != null) {
for (int i = 0, numArgs = args.length; i < numArgs; i++) {
if (i > 0) {
builder.append(", ");
}
builder.append(args[i].getSQL());
}
writeExpressions(builder, args);
}
builder.append(')');
if (fromLast && type == WindowFunctionType.NTH_VALUE) {
......@@ -542,7 +537,7 @@ public class WindowFunction extends DataAnalysisOperation {
default:
}
}
return appendTailConditions(builder).toString();
return appendTailConditions(builder);
}
@Override
......
......@@ -514,7 +514,10 @@ public class FullText {
if (data instanceof UUID) {
return "'" + data.toString() + "'";
}
return "'" + StringUtils.convertBytesToHex((byte[]) data) + "'";
byte[] bytes = (byte[]) data;
StringBuilder builder = new StringBuilder(bytes.length * 2 + 2).append('\'');
StringUtils.convertBytesToHex(builder, bytes).append('\'');
return builder.toString();
case Types.CLOB:
case Types.JAVA_OBJECT:
case Types.OTHER:
......@@ -769,13 +772,13 @@ public class FullText {
if(!multiThread) {
buff.append(", ROLLBACK");
}
buff.append(" ON ").
append(StringUtils.quoteIdentifier(schema)).
append('.').
append(StringUtils.quoteIdentifier(table)).
buff.append(" ON ");
StringUtils.quoteIdentifier(buff, schema).
append('.');
StringUtils.quoteIdentifier(buff, table).
append(" FOR EACH ROW CALL \"").
append(FullText.FullTextTrigger.class.getName()).
append('\"');
append('"');
stat.execute(buff.toString());
}
}
......@@ -1142,7 +1145,7 @@ public class FullText {
StatementBuilder buff = new StatementBuilder();
for (int columnIndex : index.keys) {
buff.appendExceptFirst(" AND ");
buff.append(StringUtils.quoteIdentifier(index.columns[columnIndex]));
StringUtils.quoteIdentifier(buff.builder(), index.columns[columnIndex]);
Object o = row[columnIndex];
if (o == null) {
buff.append(" IS NULL");
......
......@@ -281,19 +281,19 @@ public class FullTextLucene extends FullText {
StringUtils.quoteIdentifier(TRIGGER_PREFIX + table);
stat.execute("DROP TRIGGER IF EXISTS " + trigger);
if (create) {
StringBuilder buff = new StringBuilder(
StringBuilder builder = new StringBuilder(
"CREATE TRIGGER IF NOT EXISTS ");
// the trigger is also called on rollback because transaction
// rollback will not undo the changes in the Lucene index
buff.append(trigger).
append(" AFTER INSERT, UPDATE, DELETE, ROLLBACK ON ").
append(StringUtils.quoteIdentifier(schema)).
append('.').
append(StringUtils.quoteIdentifier(table)).
builder.append(trigger).
append(" AFTER INSERT, UPDATE, DELETE, ROLLBACK ON ");
StringUtils.quoteIdentifier(builder, schema).
append('.');
StringUtils.quoteIdentifier(builder, table).
append(" FOR EACH ROW CALL \"").
append(FullTextLucene.FullTextTrigger.class.getName()).
append('\"');
stat.execute(buff.toString());
stat.execute(builder.toString());
}
}
......@@ -679,22 +679,25 @@ public class FullTextLucene extends FullText {
}
private String getQuery(Object[] row) throws SQLException {
StatementBuilder buff = new StatementBuilder();
StringBuilder builder = new StringBuilder();
if (schema != null) {
buff.append(StringUtils.quoteIdentifier(schema)).append('.');
StringUtils.quoteIdentifier(builder, schema).append('.');
}
buff.append(StringUtils.quoteIdentifier(table)).append(" WHERE ");
for (int columnIndex : keys) {
buff.appendExceptFirst(" AND ");
buff.append(StringUtils.quoteIdentifier(columns[columnIndex]));
StringUtils.quoteIdentifier(builder, table).append(" WHERE ");
for (int i = 0, length = keys.length; i < length; i++) {
if (i > 0) {
builder.append(" AND ");
}
int columnIndex = keys[i];
StringUtils.quoteIdentifier(builder, columns[columnIndex]);
Object o = row[columnIndex];
if (o == null) {
buff.append(" IS NULL");
builder.append(" IS NULL");
} else {
buff.append('=').append(FullText.quoteSQL(o, columnTypes[columnIndex]));
builder.append('=').append(FullText.quoteSQL(o, columnTypes[columnIndex]));
}
}
return buff.toString();
return builder.toString();
}
}
......
......@@ -410,7 +410,8 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
buff.append(quotedName);
buff.append(" ON ").append(targetTable.getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff, comment);
}
buff.append('(').append(getColumnListSQL()).append(')');
return buff.toString();
......
......@@ -177,50 +177,47 @@ public class IndexCondition {
if (compareType == Comparison.FALSE) {
return "FALSE";
}
StatementBuilder buff = new StatementBuilder();
buff.append(column.getSQL());
StringBuilder builder = new StringBuilder();
builder.append(column.getSQL());
switch (compareType) {
case Comparison.EQUAL:
buff.append(" = ");
builder.append(" = ");
break;
case Comparison.EQUAL_NULL_SAFE:
buff.append(" IS ");
builder.append(" IS ");
break;
case Comparison.BIGGER_EQUAL:
buff.append(" >= ");
builder.append(" >= ");
break;
case Comparison.BIGGER:
buff.append(" > ");
builder.append(" > ");
break;
case Comparison.SMALLER_EQUAL:
buff.append(" <= ");
builder.append(" <= ");
break;
case Comparison.SMALLER:
buff.append(" < ");
builder.append(" < ");
break;
case Comparison.IN_LIST:
buff.append(" IN(");
for (Expression e : expressionList) {
buff.appendExceptFirst(", ");
buff.append(e.getSQL());
}
buff.append(')');
builder.append(" IN(");
Expression.writeExpressions(builder, expressionList);
builder.append(')');
break;
case Comparison.IN_QUERY:
buff.append(" IN(");
buff.append(expressionQuery.getPlanSQL());
buff.append(')');
builder.append(" IN(");
builder.append(expressionQuery.getPlanSQL());
builder.append(')');
break;
case Comparison.SPATIAL_INTERSECTS:
buff.append(" && ");
builder.append(" && ");
break;
default:
DbException.throwInternalError("type=" + compareType);
}
if (expression != null) {
buff.append(expression.getSQL());
expression.getSQL(builder);
}
return buff.toString();
return builder.toString();
}
/**
......
......@@ -1624,9 +1624,10 @@ public class JdbcDatabaseMetaData extends TraceObject implements
int spaceIndex = f.indexOf(' ');
if (spaceIndex >= 0) {
// remove 'Function' from 'INSERT Function'
f = StringUtils.trimSubstring(f, 0, spaceIndex);
StringUtils.trimSubstring(buff.builder(), f, 0, spaceIndex);
} else {
buff.append(f);
}
buff.append(f);
}
}
rs.close();
......@@ -3092,14 +3093,14 @@ public class JdbcDatabaseMetaData extends TraceObject implements
}
private static String getSchemaPattern(String pattern) {
return pattern == null ? "%" : pattern.length() == 0 ?
return pattern == null ? "%" : pattern.isEmpty() ?
Constants.SCHEMA_MAIN : pattern;
}
private static String getCatalogPattern(String catalogPattern) {
// Workaround for OpenOffice: getColumns is called with "" as the
// catalog
return catalogPattern == null || catalogPattern.length() == 0 ?
return catalogPattern == null || catalogPattern.isEmpty() ?
"%" : catalogPattern;
}
......
......@@ -44,8 +44,15 @@ public class JdbcXid extends TraceObject implements Xid {
* INTERNAL
*/
public static String toString(Xid xid) {
return PREFIX + '_' + xid.getFormatId() + '_' + StringUtils.convertBytesToHex(xid.getBranchQualifier()) + '_'
+ StringUtils.convertBytesToHex(xid.getGlobalTransactionId());
StringBuilder builder = new StringBuilder()
.append(PREFIX)
.append('_')
.append(xid.getFormatId())
.append('_');
StringUtils.convertBytesToHex(builder, xid.getBranchQualifier())
.append('_');
StringUtils.convertBytesToHex(builder, xid.getGlobalTransactionId());
return builder.toString();
}
/**
......
......@@ -301,8 +301,8 @@ public class Trace {
buff.append(' ');
}
buff.append("*/");
StringUtils.javaEncode(sql, buff);
StringUtils.javaEncode(params, buff);
StringUtils.javaEncode(sql, buff, false);
StringUtils.javaEncode(params, buff, false);
buff.append(';');
sql = buff.toString();
traceWriter.write(TraceSystem.INFO, module, sql, null);
......
......@@ -312,8 +312,9 @@ public class TraceObject {
if (x == null) {
return "null";
}
return "org.h2.util.StringUtils.convertHexToBytes(\"" +
StringUtils.convertBytesToHex(x) + "\")";
StringBuilder builder = new StringBuilder(x.length * 2 + 45)
.append("org.h2.util.StringUtils.convertHexToBytes(\"");
return StringUtils.convertBytesToHex(builder, x).append("\")").toString();
}
/**
......
......@@ -35,7 +35,7 @@
57014=Befehl wurde abgebrochen oder das Session-Timeout ist abgelaufen
90000=Funktion {0} muss Zeilen zurückgeben
90001=Methode nicht zulässig für eine Abfrage. Erlaubt sind execute oder executeQuery, nicht jedoch executeUpdate
90002=Methode nur zulässig for eine Abfrage. Erlaubt sind execute oder executeUpdate, nicht jedoch executeQuery
90002=Methode nur zulässig für eine Abfrage. Erlaubt sind execute oder executeUpdate, nicht jedoch executeQuery
90003=Hexadezimal Zahl mit einer ungeraden Anzahl Zeichen: {0}
90004=Hexadezimal Zahl enthält unerlaubtes Zeichen: {0}
90006=Die Sequenz {0} hat keine freien Nummern mehr
......
......@@ -12,8 +12,6 @@ import org.h2.expression.Expression;
import org.h2.expression.ExpressionColumn;
import org.h2.table.Column;
import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils;
import org.h2.util.Utils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
......@@ -118,18 +116,21 @@ public class SortOrder implements Comparator<Value[]> {
* @return the SQL snippet
*/
public String getSQL(Expression[] list, int visible) {
StatementBuilder buff = new StatementBuilder();
StringBuilder builder = new StringBuilder();
int i = 0;
for (int idx : queryColumnIndexes) {
buff.appendExceptFirst(", ");
if (i > 0) {
builder.append(", ");
}
if (idx < visible) {
buff.append(idx + 1);
builder.append(idx + 1);
} else {
buff.append('=').append(StringUtils.unEnclose(list[idx].getSQL()));
builder.append('=');
list[idx].getUnenclosedSQL(builder);
}
typeToString(buff.builder(), sortTypes[i++]);
typeToString(builder, sortTypes[i++]);
}
return buff.toString();
return builder.toString();
}
/**
......
......@@ -161,7 +161,7 @@ public class UpdatableRow {
for (int i = 0; i < columnCount; i++) {
buff.appendExceptFirst(",");
String col = result.getColumnName(i);
buff.append(StringUtils.quoteIdentifier(col));
StringUtils.quoteIdentifier(buff.builder(), col);
if (set) {
buff.append("=? ");
}
......@@ -173,7 +173,7 @@ public class UpdatableRow {
buff.resetCount();
for (String k : key) {
buff.appendExceptFirst(" AND ");
buff.append(StringUtils.quoteIdentifier(k)).append("=?");
StringUtils.quoteIdentifier(buff.builder(), k).append("=?");
}
}
......@@ -204,11 +204,11 @@ public class UpdatableRow {
// return rs.getInt(1) == 0;
// }
private void appendTableName(StatementBuilder buff) {
private void appendTableName(StringBuilder builder) {
if (schemaName != null && schemaName.length() > 0) {
buff.append(StringUtils.quoteIdentifier(schemaName)).append('.');
StringUtils.quoteIdentifier(builder, schemaName).append('.');
}
buff.append(StringUtils.quoteIdentifier(tableName));
StringUtils.quoteIdentifier(builder, tableName);
}
/**
......@@ -221,7 +221,7 @@ public class UpdatableRow {
StatementBuilder buff = new StatementBuilder("SELECT ");
appendColumnList(buff, false);
buff.append(" FROM ");
appendTableName(buff);
appendTableName(buff.builder());
appendKeyCondition(buff);
PreparedStatement prep = conn.prepareStatement(buff.toString());
setKey(prep, 1, row);
......@@ -245,7 +245,7 @@ public class UpdatableRow {
*/
public void deleteRow(Value[] current) throws SQLException {
StatementBuilder buff = new StatementBuilder("DELETE FROM ");
appendTableName(buff);
appendTableName(buff.builder());
appendKeyCondition(buff);
PreparedStatement prep = conn.prepareStatement(buff.toString());
setKey(prep, 1, current);
......@@ -265,7 +265,7 @@ public class UpdatableRow {
*/
public void updateRow(Value[] current, Value[] updateRow) throws SQLException {
StatementBuilder buff = new StatementBuilder("UPDATE ");
appendTableName(buff);
appendTableName(buff.builder());
buff.append(" SET ");
appendColumnList(buff, true);
// TODO updatable result set: we could add all current values to the
......@@ -297,7 +297,7 @@ public class UpdatableRow {
*/
public void insertRow(Value[] row) throws SQLException {
StatementBuilder buff = new StatementBuilder("INSERT INTO ");
appendTableName(buff);
appendTableName(buff.builder());
buff.append('(');
appendColumnList(buff, false);
buff.append(")VALUES(");
......
......@@ -38,7 +38,8 @@ public class Constant extends SchemaObjectBase {
@Override
public String getCreateSQL() {
return "CREATE CONSTANT " + getSQL() + " VALUE " + value.getSQL();
StringBuilder builder = new StringBuilder().append("CREATE CONSTANT ").append(getSQL()).append(" VALUE ");
return value.getSQL(builder).toString();
}
@Override
......
......@@ -345,9 +345,11 @@ public class TriggerObject extends SchemaObjectBase {
buff.append(" QUEUE ").append(queueSize);
}
if (triggerClassName != null) {
buff.append(" CALL ").append(Parser.quoteIdentifier(triggerClassName));
buff.append(" CALL ");
Parser.quoteIdentifier(buff, triggerClassName);
} else {
buff.append(" AS ").append(StringUtils.quoteStringSQL(triggerSource));
buff.append(" AS ");
StringUtils.quoteStringSQL(buff, triggerSource);
}
return buff.toString();
}
......
......@@ -180,7 +180,7 @@ public class PgServerThread implements Runnable {
" (" + (version >> 16) + "." + (version & 0xff) + ")");
while (true) {
String param = readString();
if (param.length() == 0) {
if (param.isEmpty()) {
break;
}
String value = readString();
......
......@@ -240,14 +240,15 @@ public class PageParser {
if (s == null) {
return null;
}
int length = s.length();
if (convertBreakAndSpace) {
if (s.length() == 0) {
if (length == 0) {
return "&nbsp;";
}
}
StringBuilder buff = new StringBuilder(s.length());
StringBuilder buff = new StringBuilder(length);
boolean convertSpace = true;
for (int i = 0; i < s.length(); i++) {
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
if (c == ' ' || c == '\t') {
// convert tabs into spaces
......@@ -312,11 +313,12 @@ public class PageParser {
if (s == null) {
return null;
}
if (s.length() == 0) {
int length = s.length();
if (length == 0) {
return "";
}
StringBuilder buff = new StringBuilder(s.length());
for (int i = 0; i < s.length(); i++) {
StringBuilder buff = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
switch (c) {
case '"':
......
......@@ -167,7 +167,7 @@ class WebSession {
return;
}
sql = sql.trim();
if (sql.length() == 0) {
if (sql.isEmpty()) {
return;
}
if (commandHistory.size() > MAX_HISTORY) {
......
......@@ -51,7 +51,7 @@ public class FilePathZip extends FilePath {
public boolean exists() {
try {
String entryName = getEntryName();
if (entryName.length() == 0) {
if (entryName.isEmpty()) {
return true;
}
try (ZipFile file = openZipFile()) {
......@@ -88,7 +88,7 @@ public class FilePathZip extends FilePath {
public boolean isDirectory() {
try {
String entryName = getEntryName();
if (entryName.length() == 0) {
if (entryName.isEmpty()) {
return true;
}
try (ZipFile file = openZipFile()) {
......
......@@ -174,7 +174,7 @@ public class Column {
getCreateSQL();
throw DbException.get(
ErrorCode.DATA_CONVERSION_ERROR_1, e,
v.getSQL() + " (" + target + ")");
v.getTraceSQL() + " (" + target + ")");
}
throw e;
}
......@@ -496,7 +496,7 @@ public class Column {
private String getCreateSQL(boolean includeName) {
StringBuilder buff = new StringBuilder();
if (includeName && name != null) {
buff.append(Parser.quoteIdentifier(name)).append(' ');
Parser.quoteIdentifier(buff, name).append(' ');
}
if (originalSQL != null) {
buff.append(originalSQL);
......@@ -546,20 +546,17 @@ public class Column {
}
if (defaultExpression != null) {
String sql = defaultExpression.getSQL();
if (sql != null) {
if (isComputed) {
buff.append(" AS ").append(sql);
} else if (defaultExpression != null) {
buff.append(" DEFAULT ").append(sql);
}
if (isComputed) {
buff.append(" AS ");
defaultExpression.getSQL(buff);
} else if (defaultExpression != null) {
buff.append(" DEFAULT ");
defaultExpression.getSQL(buff);
}
}
if (onUpdateExpression != null) {
String sql = onUpdateExpression.getSQL();
if (sql != null) {
buff.append(" ON UPDATE ").append(sql);
}
buff.append(" ON UPDATE ");
onUpdateExpression.getSQL(buff);
}
if (!nullable) {
buff.append(" NOT NULL");
......@@ -576,7 +573,8 @@ public class Column {
buff.append(" SELECTIVITY ").append(selectivity);
}
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff, comment);
}
if (checkConstraint != null) {
buff.append(" CHECK ").append(checkConstraintSQL);
......
......@@ -49,8 +49,8 @@ public class LinkSchema {
try {
c2 = JdbcUtils.getConnection(driver, url, user, password);
stat = conn.createStatement();
stat.execute("CREATE SCHEMA IF NOT EXISTS " +
StringUtils.quoteIdentifier(targetSchema));
stat.execute(StringUtils.quoteIdentifier(new StringBuilder("CREATE SCHEMA IF NOT EXISTS "), targetSchema)
.toString());
//Workaround for PostgreSQL to avoid index names
if (url.startsWith("jdbc:postgresql:")) {
rs = c2.getMetaData().getTables(null, sourceSchema, null,
......@@ -61,29 +61,23 @@ public class LinkSchema {
while (rs.next()) {
String table = rs.getString("TABLE_NAME");
StringBuilder buff = new StringBuilder();
buff.append("DROP TABLE IF EXISTS ").
append(StringUtils.quoteIdentifier(targetSchema)).
append('.').
append(StringUtils.quoteIdentifier(table));
buff.append("DROP TABLE IF EXISTS ");
StringUtils.quoteIdentifier(buff, targetSchema).
append('.');
StringUtils.quoteIdentifier(buff, table);
stat.execute(buff.toString());
buff = new StringBuilder();
buff.append("CREATE LINKED TABLE ").
append(StringUtils.quoteIdentifier(targetSchema)).
append('.').
append(StringUtils.quoteIdentifier(table)).
append('(').
append(StringUtils.quoteStringSQL(driver)).
append(", ").
append(StringUtils.quoteStringSQL(url)).
append(", ").
append(StringUtils.quoteStringSQL(user)).
append(", ").
append(StringUtils.quoteStringSQL(password)).
append(", ").
append(StringUtils.quoteStringSQL(sourceSchema)).
append(", ").
append(StringUtils.quoteStringSQL(table)).
append(')');
buff.setLength(0);
buff.append("CREATE LINKED TABLE ");
StringUtils.quoteIdentifier(buff, targetSchema).
append('.');
StringUtils.quoteIdentifier(buff, table).
append('(');
StringUtils.quoteStringSQL(buff, driver).append(", ");
StringUtils.quoteStringSQL(buff, url).append(", ");
StringUtils.quoteStringSQL(buff, user).append(", ");
StringUtils.quoteStringSQL(buff, password).append(", ");
StringUtils.quoteStringSQL(buff, sourceSchema).append(", ");
StringUtils.quoteStringSQL(buff, table).append(')');
stat.execute(buff.toString());
result.addRow(table);
}
......
......@@ -1896,11 +1896,12 @@ public class MetaTable extends Table {
case SESSION_STATE: {
for (String name : session.getVariableNames()) {
Value v = session.getVariable(name);
StringBuilder builder = new StringBuilder().append("SET @").append(name).append(' ');
v.getSQL(builder);
add(rows,
// KEY
"@" + name,
// SQL
"SET @" + name + " " + v.getSQL()
builder.toString()
);
}
for (Table table : session.getLocalTempTables()) {
......@@ -1917,7 +1918,7 @@ public class MetaTable extends Table {
"SET SCHEMA_SEARCH_PATH ");
for (String p : path) {
buff.appendExceptFirst(", ");
buff.append(StringUtils.quoteIdentifier(p));
StringUtils.quoteIdentifier(buff.builder(), p);
}
add(rows,
// KEY
......@@ -1932,7 +1933,7 @@ public class MetaTable extends Table {
// KEY
"SCHEMA",
// SQL
"SET SCHEMA " + StringUtils.quoteIdentifier(schema)
StringUtils.quoteIdentifier(new StringBuilder("SET SCHEMA "), schema).toString()
);
}
break;
......
......@@ -72,11 +72,15 @@ public class RangeTable extends Table {
@Override
public String getSQL() {
String sql = NAME + "(" + min.getSQL() + ", " + max.getSQL();
StringBuilder builder = new StringBuilder();
builder.append(NAME).append('(');
min.getSQL(builder).append(", ");
max.getSQL(builder);
if (step != null) {
sql += ", " + step.getSQL();
builder.append(", ");
step.getSQL(builder);
}
return sql + ")";
return builder.append(')').toString();
}
@Override
......
......@@ -108,7 +108,8 @@ public abstract class TableBase extends Table {
}
buff.append(getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff.builder(), comment);
}
buff.append("(\n ");
for (Column column : columns) {
......@@ -124,7 +125,7 @@ public abstract class TableBase extends Table {
}
if (d == null || !tableEngine.endsWith(d)) {
buff.append("\nENGINE ");
buff.append(StringUtils.quoteIdentifier(tableEngine));
StringUtils.quoteIdentifier(buff.builder(), tableEngine);
}
}
if (!tableEngineParams.isEmpty()) {
......@@ -132,7 +133,7 @@ public abstract class TableBase extends Table {
buff.resetCount();
for (String parameter : tableEngineParams) {
buff.appendExceptFirst(", ");
buff.append(StringUtils.quoteIdentifier(parameter));
StringUtils.quoteIdentifier(buff.builder(), parameter);
}
}
if (!isPersistIndexes() && !isPersistData()) {
......
......@@ -747,75 +747,77 @@ public class TableFilter implements ColumnResolver {
}
/**
* Get the query execution plan text to use for this table filter.
* Get the query execution plan text to use for this table filter and append
* it to the specified builder.
*
* @param builder string builder to append to
* @param isJoin if this is a joined table
* @return the SQL statement snippet
* @return the specified builder
*/
public String getPlanSQL(boolean isJoin) {
StringBuilder buff = new StringBuilder();
public StringBuilder getPlanSQL(StringBuilder builder, boolean isJoin) {
if (isJoin) {
if (joinOuter) {
buff.append("LEFT OUTER JOIN ");
builder.append("LEFT OUTER JOIN ");
} else {
buff.append("INNER JOIN ");
builder.append("INNER JOIN ");
}
}
if (nestedJoin != null) {
StringBuilder buffNested = new StringBuilder();
TableFilter n = nestedJoin;
do {
buffNested.append(n.getPlanSQL(n != nestedJoin));
buffNested.append('\n');
n.getPlanSQL(buffNested, n != nestedJoin).append('\n');
n = n.getJoin();
} while (n != null);
String nested = buffNested.toString();
boolean enclose = !nested.startsWith("(");
if (enclose) {
buff.append("(\n");
builder.append("(\n");
}
buff.append(StringUtils.indent(nested, 4, false));
StringUtils.indent(builder, nested, 4, false);
if (enclose) {
buff.append(')');
builder.append(')');
}
if (isJoin) {
buff.append(" ON ");
builder.append(" ON ");
if (joinCondition == null) {
// need to have a ON expression,
// otherwise the nesting is unclear
buff.append("1=1");
builder.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
joinCondition.getUnenclosedSQL(builder);
}
}
return buff.toString();
return builder;
}
if (table.isView() && ((TableView) table).isRecursive()) {
buff.append(table.getSchema().getSQL()).append('.').append(Parser.quoteIdentifier(table.getName()));
builder.append(table.getSchema().getSQL()).append('.');
Parser.quoteIdentifier(builder, table.getName());
} else {
buff.append(table.getSQL());
builder.append(table.getSQL());
}
if (table.isView() && ((TableView) table).isInvalid()) {
throw DbException.get(ErrorCode.VIEW_IS_INVALID_2, table.getName(), "not compiled");
}
if (alias != null) {
buff.append(' ').append(Parser.quoteIdentifier(alias));
builder.append(' ');
Parser.quoteIdentifier(builder, alias);
}
if (indexHints != null) {
buff.append(" USE INDEX (");
builder.append(" USE INDEX (");
boolean first = true;
for (String index : indexHints.getAllowedIndexes()) {
if (!first) {
buff.append(", ");
builder.append(", ");
} else {
first = false;
}
buff.append(Parser.quoteIdentifier(index));
Parser.quoteIdentifier(builder, index);
}
buff.append(")");
builder.append(")");
}
if (index != null) {
buff.append('\n');
builder.append('\n');
StatementBuilder planBuff = new StatementBuilder();
if (joinBatch != null) {
IndexLookupBatch lookupBatch = joinBatch.getLookupBatch(joinFilterId);
......@@ -842,28 +844,28 @@ public class TableFilter implements ColumnResolver {
if (plan.indexOf('\n') >= 0) {
plan += "\n";
}
buff.append(StringUtils.indent("/* " + plan + " */", 4, false));
StringUtils.indent(builder, "/* " + plan + " */", 4, false);
}
if (isJoin) {
buff.append("\n ON ");
builder.append("\n ON ");
if (joinCondition == null) {
// need to have a ON expression, otherwise the nesting is
// unclear
buff.append("1=1");
builder.append("1=1");
} else {
buff.append(StringUtils.unEnclose(joinCondition.getSQL()));
joinCondition.getUnenclosedSQL(builder);
}
}
if (filterCondition != null) {
buff.append('\n');
builder.append('\n');
String condition = StringUtils.unEnclose(filterCondition.getSQL());
condition = "/* WHERE " + StringUtils.quoteRemarkSQL(condition) + "\n*/";
buff.append(StringUtils.indent(condition, 4, false));
StringUtils.indent(builder, condition, 4, false);
}
if (scanCount > 0) {
buff.append("\n /* scanCount: ").append(scanCount).append(" */");
builder.append("\n /* scanCount: ").append(scanCount).append(" */");
}
return buff.toString();
return builder;
}
/**
......
......@@ -372,19 +372,15 @@ public class TableLink extends Table {
}
buff.append("LINKED TABLE ").append(getSQL());
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff, comment);
}
buff.append('(').
append(StringUtils.quoteStringSQL(driver)).
append(", ").
append(StringUtils.quoteStringSQL(url)).
append(", ").
append(StringUtils.quoteStringSQL(user)).
append(", ").
append(StringUtils.quoteStringSQL(password)).
append(", ").
append(StringUtils.quoteStringSQL(originalTable)).
append(')');
buff.append('(');
StringUtils.quoteStringSQL(buff, driver).append(", ");
StringUtils.quoteStringSQL(buff, url).append(", ");
StringUtils.quoteStringSQL(buff, user).append(", ");
StringUtils.quoteStringSQL(buff, password).append(", ");
StringUtils.quoteStringSQL(buff, originalTable).append(')');
if (emitUpdates) {
buff.append(" EMIT UPDATES");
}
......@@ -510,7 +506,8 @@ public class TableLink extends Table {
int i = 1;
for (Value v : params) {
buff.appendExceptFirst(", ");
buff.append(i++).append(": ").append(v.getSQL());
buff.append(i++).append(": ");
v.getSQL(buff.builder());
}
buff.append('}');
}
......
......@@ -348,7 +348,8 @@ public class TableView extends Table {
}
buff.append(quotedName);
if (comment != null) {
buff.append(" COMMENT ").append(StringUtils.quoteStringSQL(comment));
buff.append(" COMMENT ");
StringUtils.quoteStringSQL(buff.builder(), comment);
}
if (columns != null && columns.length > 0) {
buff.append('(');
......@@ -467,7 +468,8 @@ public class TableView extends Table {
@Override
public String getSQL() {
if (isTemporary() && querySQL != null) {
return "(\n" + StringUtils.indent(querySQL) + ")";
StringBuilder builder = new StringBuilder(querySQL.length() + 16).append("(\n");
return StringUtils.indent(builder, querySQL, 4, true).append(')').toString();
}
return super.getSQL();
}
......
......@@ -108,7 +108,7 @@ public class Backup extends Tool {
private void process(String zipFileName, String directory, String db,
boolean quiet) throws SQLException {
List<String> list;
boolean allFiles = db != null && db.length() == 0;
boolean allFiles = db != null && db.isEmpty();
if (allFiles) {
list = FileUtils.newDirectoryStream(directory);
} else {
......
......@@ -228,7 +228,7 @@ public class Csv implements SimpleRowSource {
for (int i = 0; i < columnNames.length; i++) {
StringBuilder buff = new StringBuilder();
String n = columnNames[i];
if (n == null || n.length() == 0) {
if (n == null || n.isEmpty()) {
buff.append('C').append(i + 1);
} else {
buff.append(n);
......@@ -350,7 +350,7 @@ public class Csv implements SimpleRowSource {
list.add(v);
}
} else {
if (v.length() == 0) {
if (v.isEmpty()) {
v = "COLUMN" + list.size();
} else if (!caseSensitiveColumnNames && isSimpleColumnName(v)) {
v = StringUtils.toUpperEnglish(v);
......@@ -827,13 +827,13 @@ public class Csv implements SimpleRowSource {
String charset = null;
String[] keyValuePairs = StringUtils.arraySplit(options, ' ', false);
for (String pair : keyValuePairs) {
if (pair.length() == 0) {
if (pair.isEmpty()) {
continue;
}
int index = pair.indexOf('=');
String key = StringUtils.trim(pair.substring(0, index), true, true, " ");
String value = pair.substring(index + 1);
char ch = value.length() == 0 ? 0 : value.charAt(0);
char ch = value.isEmpty() ? 0 : value.charAt(0);
if (isParam(key, "escape", "esc", "escapeCharacter")) {
setEscapeCharacter(ch);
} else if (isParam(key, "fieldDelimiter", "fieldDelim")) {
......
......@@ -156,12 +156,13 @@ public class MultiDimension implements Comparator<long[]> {
public String generatePreparedQuery(String table, String scalarColumn,
String[] columns) {
StringBuilder buff = new StringBuilder("SELECT D.* FROM ");
buff.append(StringUtils.quoteIdentifier(table)).
append(" D, TABLE(_FROM_ BIGINT=?, _TO_ BIGINT=?) WHERE ").
append(StringUtils.quoteIdentifier(scalarColumn)).
StringUtils.quoteIdentifier(buff, table).
append(" D, TABLE(_FROM_ BIGINT=?, _TO_ BIGINT=?) WHERE ");
StringUtils.quoteIdentifier(buff, scalarColumn).
append(" BETWEEN _FROM_ AND _TO_");
for (String col : columns) {
buff.append(" AND ").append(StringUtils.quoteIdentifier(col)).
buff.append(" AND ");
StringUtils.quoteIdentifier(buff, col).
append("+1 BETWEEN ?+1 AND ?+1");
}
return buff.toString();
......
......@@ -417,7 +417,7 @@ public class Recover extends Tool implements DataHandler {
}
}
private String getSQL(String column, Value v) {
private void getSQL(StringBuilder builder, String column, Value v) {
if (v instanceof ValueLob) {
ValueLob lob = (ValueLob) v;
byte[] small = lob.getSmall();
......@@ -428,7 +428,8 @@ public class Recover extends Tool implements DataHandler {
dumpLob(file, true);
file += ".comp";
}
return "READ_" + type + "('" + file + ".txt')";
builder.append("READ_").append(type).append("('").append(file).append(".txt')");
return;
}
} else if (v instanceof ValueLobDb) {
ValueLobDb lob = (ValueLobDb) v;
......@@ -437,25 +438,25 @@ public class Recover extends Tool implements DataHandler {
int type = lob.getType();
long id = lob.getLobId();
long precision = lob.getPrecision();
String m;
String columnType;
if (type == Value.BLOB) {
columnType = "BLOB";
m = "READ_BLOB";
builder.append("READ_BLOB");
} else {
columnType = "CLOB";
m = "READ_CLOB";
builder.append("READ_CLOB");
}
if (lobMaps) {
m += "_MAP";
builder.append("_MAP");
} else {
m += "_DB";
builder.append("_DB");
}
columnTypeMap.put(column, columnType);
return m + "(" + id + ", " + precision + ")";
builder.append('(').append(id).append(", ").append(precision).append(')');
return;
}
}
return v.getSQL();
v.getSQL(builder);
}
private void setDatabaseName(String name) {
......@@ -666,9 +667,11 @@ public class Recover extends Tool implements DataHandler {
if (!init) {
setStorage(Integer.parseInt(tableId));
// init the column types
StringBuilder builder = new StringBuilder();
for (valueId = 0; valueId < recordLength; valueId++) {
String columnName = storageName + "." + valueId;
getSQL(columnName, values[valueId]);
builder.setLength(0);
getSQL(builder, columnName, values[valueId]);
}
createTemporaryTable(writer);
init = true;
......@@ -681,7 +684,7 @@ public class Recover extends Tool implements DataHandler {
buff.append(", ");
}
String columnName = storageName + "." + valueId;
buff.append(getSQL(columnName, values[valueId]));
getSQL(buff, columnName, values[valueId]);
}
buff.append(");");
writer.println(buff.toString());
......@@ -729,10 +732,11 @@ public class Recover extends Tool implements DataHandler {
try {
for (int seq = 0;; seq++) {
int l = IOUtils.readFully(in, block, block.length);
String x = StringUtils.convertBytesToHex(block, l);
if (l > 0) {
writer.println("INSERT INTO INFORMATION_SCHEMA.LOB_BLOCKS " +
"VALUES(" + lobId + ", " + seq + ", '" + x + "');");
writer.print("INSERT INTO INFORMATION_SCHEMA.LOB_BLOCKS " +
"VALUES(" + lobId + ", " + seq + ", '");
writer.print(StringUtils.convertBytesToHex(block, l));
writer.println("');");
}
if (l != len) {
break;
......@@ -991,7 +995,7 @@ public class Recover extends Tool implements DataHandler {
append(" VALUES(");
for (int i = 0; i < row.getColumnCount(); i++) {
buff.appendExceptFirst(", ");
buff.append(row.getValue(i).getSQL());
row.getValue(i).getSQL(buff.builder());
}
buff.append(");");
writer.println(buff.toString());
......@@ -1443,12 +1447,12 @@ public class Recover extends Tool implements DataHandler {
byte[] salt = MathUtils.secureRandomBytes(Constants.SALT_LEN);
byte[] passwordHash = SHA256.getHashWithSalt(
userPasswordHash, salt);
StringBuilder buff = new StringBuilder();
buff.append("SALT '").
append(StringUtils.convertBytesToHex(salt)).
append("' HASH '").
append(StringUtils.convertBytesToHex(passwordHash)).
append('\'');
StringBuilder buff = new StringBuilder()
.append("SALT '");
StringUtils.convertBytesToHex(buff, salt)
.append("' HASH '");
StringUtils.convertBytesToHex(buff, passwordHash)
.append('\'');
byte[] replacement = buff.toString().getBytes();
System.arraycopy(replacement, 0, s.getBytes(),
saltIndex, replacement.length);
......@@ -1497,7 +1501,7 @@ public class Recover extends Tool implements DataHandler {
sb.append(", ");
}
String columnName = storageName + "." + valueId;
sb.append(getSQL(columnName, v));
getSQL(sb, columnName, v);
} catch (Exception e) {
writeDataError(writer, "exception " + e, s.getBytes());
} catch (OutOfMemoryError e) {
......
......@@ -205,7 +205,7 @@ public class RunScript extends Tool {
break;
}
String trim = sql.trim();
if (trim.length() == 0) {
if (trim.isEmpty()) {
continue;
}
if (trim.startsWith("@") && StringUtils.toUpperEnglish(trim).
......
......@@ -220,7 +220,7 @@ public class Shell extends Tool implements Runnable {
break;
}
String trimmed = line.trim();
if (trimmed.length() == 0) {
if (trimmed.isEmpty()) {
continue;
}
boolean end = trimmed.endsWith(";");
......@@ -366,7 +366,7 @@ public class Shell extends Tool implements Runnable {
println("[Enter] Hide");
print("Password ");
String password = readLine();
if (password.length() == 0) {
if (password.isEmpty()) {
password = readPassword();
}
conn = JdbcUtils.getConnection(driver, url, user, password);
......@@ -433,7 +433,7 @@ public class Shell extends Tool implements Runnable {
private String readLine(String defaultValue) throws IOException {
String s = readLine();
return s.length() == 0 ? defaultValue : s;
return s.isEmpty() ? defaultValue : s;
}
private String readLine() throws IOException {
......
......@@ -6,7 +6,7 @@ package org.h2.util;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.engine.Session;
import org.h2.expression.Expression;
......@@ -57,51 +57,23 @@ public class ColumnNamer {
*/
public String getColumnName(Expression columnExp, int indexOfColumn, String columnNameOverride) {
// try a name from the column name override
String columnName = null;
if (columnNameOverride != null) {
columnName = columnNameOverride;
if (!isAllowableColumnName(columnName)) {
columnName = fixColumnName(columnName);
}
if (!isAllowableColumnName(columnName)) {
columnName = null;
}
}
// try a name from the column alias
if (columnName == null && columnExp.getAlias() != null && !DEFAULT_COLUMN_NAME.equals(columnExp.getAlias())) {
columnName = columnExp.getAlias();
if (!isAllowableColumnName(columnName)) {
columnName = fixColumnName(columnName);
}
if (!isAllowableColumnName(columnName)) {
columnName = null;
}
}
// try a name derived from the column expression SQL
if (columnName == null && columnExp.getColumnName() != null
&& !DEFAULT_COLUMN_NAME.equals(columnExp.getColumnName())) {
columnName = columnExp.getColumnName();
if (!isAllowableColumnName(columnName)) {
columnName = fixColumnName(columnName);
}
if (!isAllowableColumnName(columnName)) {
columnName = null;
}
}
// try a name derived from the column expression plan SQL
if (columnName == null && columnExp.getSQL() != null && !DEFAULT_COLUMN_NAME.equals(columnExp.getSQL())) {
columnName = columnExp.getSQL();
if (!isAllowableColumnName(columnName)) {
columnName = fixColumnName(columnName);
}
if (!isAllowableColumnName(columnName)) {
columnName = null;
}
}
// go with a innocuous default name pattern
String columnName = getColumnName(columnNameOverride, null);
if (columnName == null) {
columnName = configuration.getDefaultColumnNamePattern()
.replace("$$", Integer.toString(indexOfColumn + 1));
// try a name from the column alias
columnName = getColumnName(columnExp.getAlias(), DEFAULT_COLUMN_NAME);
if (columnName == null) {
// try a name derived from the column expression SQL
columnName = getColumnName(columnExp.getColumnName(), DEFAULT_COLUMN_NAME);
if (columnName == null) {
// try a name derived from the column expression plan SQL
columnName = getColumnName(columnExp.getSQL(), DEFAULT_COLUMN_NAME);
// go with a innocuous default name pattern
if (columnName == null) {
columnName = configuration.getDefaultColumnNamePattern()
.replace("$$", Integer.toString(indexOfColumn + 1));
}
}
}
}
if (existingColumnNames.contains(columnName) && configuration.isGenerateUniqueColumnNames()) {
columnName = generateUniqueName(columnName);
......@@ -110,6 +82,21 @@ public class ColumnNamer {
return columnName;
}
private String getColumnName(String proposedName, String disallowedName) {
String columnName = null;
if (proposedName != null && !proposedName.equals(disallowedName)) {
if (isAllowableColumnName(proposedName)) {
columnName = proposedName;
} else {
proposedName = fixColumnName(proposedName);
if (isAllowableColumnName(proposedName)) {
columnName = proposedName;
}
}
}
return columnName;
}
private String generateUniqueName(String columnName) {
String newColumnName = columnName;
int loopCount = 2;
......@@ -124,26 +111,31 @@ public class ColumnNamer {
}
private boolean isAllowableColumnName(String proposedName) {
// check null
if (proposedName == null) {
return false;
}
// check size limits
if (proposedName.length() > configuration.getMaxIdentiferLength() || proposedName.length() == 0) {
int length = proposedName.length();
if (length > configuration.getMaxIdentiferLength() || length == 0) {
return false;
}
Matcher match = configuration.getCompiledRegularExpressionMatchAllowed().matcher(proposedName);
return match.matches();
Pattern allowed = configuration.getCompiledRegularExpressionMatchAllowed();
return allowed == null || allowed.matcher(proposedName).matches();
}
private String fixColumnName(String proposedName) {
Matcher match = configuration.getCompiledRegularExpressionMatchDisallowed().matcher(proposedName);
proposedName = match.replaceAll("");
Pattern disallowed = configuration.getCompiledRegularExpressionMatchDisallowed();
if (disallowed == null) {
proposedName = StringUtils.replaceAll(proposedName, "\u0000", "");
} else {
proposedName = disallowed.matcher(proposedName).replaceAll("");
}
// check size limits - then truncate
if (proposedName.length() > configuration.getMaxIdentiferLength()) {
proposedName = proposedName.substring(0, configuration.getMaxIdentiferLength());
int length = proposedName.length(), maxLength = configuration.getMaxIdentiferLength();
if (length > maxLength) {
proposedName = proposedName.substring(0, maxLength);
}
return proposedName;
......
......@@ -40,8 +40,7 @@ public class ColumnNamerConfiguration {
this.defaultColumnNamePattern = defaultColumnNamePattern;
this.generateUniqueColumnNames = generateUniqueColumnNames;
compiledRegularExpressionMatchAllowed = Pattern.compile(regularExpressionMatchAllowed);
compiledRegularExpressionMatchDisallowed = Pattern.compile(regularExpressionMatchDisallowed);
recompilePatterns();
}
public int getMaxIdentiferLength() {
......@@ -80,6 +79,11 @@ public class ColumnNamerConfiguration {
this.defaultColumnNamePattern = defaultColumnNamePattern;
}
/**
* Returns compiled pattern for allowed names.
*
* @return compiled pattern, or null for default
*/
public Pattern getCompiledRegularExpressionMatchAllowed() {
return compiledRegularExpressionMatchAllowed;
}
......@@ -88,6 +92,11 @@ public class ColumnNamerConfiguration {
this.compiledRegularExpressionMatchAllowed = compiledRegularExpressionMatchAllowed;
}
/**
* Returns compiled pattern for disallowed names.
*
* @return compiled pattern, or null for default
*/
public Pattern getCompiledRegularExpressionMatchDisallowed() {
return compiledRegularExpressionMatchDisallowed;
}
......@@ -138,8 +147,11 @@ public class ColumnNamerConfiguration {
private void recompilePatterns() {
try {
// recompile RE patterns
setCompiledRegularExpressionMatchAllowed(Pattern.compile(getRegularExpressionMatchAllowed()));
setCompiledRegularExpressionMatchDisallowed(Pattern.compile(getRegularExpressionMatchDisallowed()));
setCompiledRegularExpressionMatchAllowed(
regularExpressionMatchAllowed != null ? Pattern.compile(regularExpressionMatchAllowed) : null);
setCompiledRegularExpressionMatchDisallowed(
regularExpressionMatchDisallowed != null ? Pattern.compile(regularExpressionMatchDisallowed)
: null);
} catch (Exception e) {
configure(REGULAR);
throw e;
......@@ -147,7 +159,7 @@ public class ColumnNamerConfiguration {
}
public static ColumnNamerConfiguration getDefault() {
return new ColumnNamerConfiguration(Integer.MAX_VALUE, "(?m)(?s).+", "(?m)(?s)[\\x00]", "_UNNAMED_$$", false);
return new ColumnNamerConfiguration(Integer.MAX_VALUE, null, null, "_UNNAMED_$$", false);
}
private static String unquoteString(String s) {
......@@ -220,8 +232,8 @@ public class ColumnNamerConfiguration {
case Ignite:
default:
setMaxIdentiferLength(Integer.MAX_VALUE);
setRegularExpressionMatchAllowed("(?m)(?s).+");
setRegularExpressionMatchDisallowed("(?m)(?s)[\\x00]");
setRegularExpressionMatchAllowed(null);
setRegularExpressionMatchDisallowed(null);
setDefaultColumnNamePattern("_UNNAMED_$$");
setGenerateUniqueColumnNames(false);
break;
......
......@@ -1511,18 +1511,17 @@ public class DateTimeUtils {
/**
* Formats timestamp with time zone as string.
*
* @param buff the target string builder
* @param dateValue the year-month-day bit field
* @param timeNanos nanoseconds since midnight
* @param timeZoneOffsetMins the time zone offset in minutes
* @return formatted string
*/
public static String timestampTimeZoneToString(long dateValue, long timeNanos, short timeZoneOffsetMins) {
StringBuilder buff = new StringBuilder(ValueTimestampTimeZone.MAXIMUM_PRECISION);
public static void appendTimestampTimeZone(StringBuilder buff, long dateValue, long timeNanos,
short timeZoneOffsetMins) {
appendDate(buff, dateValue);
buff.append(' ');
appendTime(buff, timeNanos);
appendTimeZone(buff, timeZoneOffsetMins);
return buff.toString();
}
/**
......
......@@ -383,8 +383,11 @@ public class IntervalUtils {
}
/**
* Formats interval as a string.
* Formats interval as a string and appends it to a specified string
* builder.
*
* @param buff
* string builder to append to
* @param qualifier
* qualifier of the interval
* @param negative
......@@ -393,12 +396,11 @@ public class IntervalUtils {
* the value of leading field
* @param remaining
* the value of all remaining fields
* @return string representation of the specified interval
* @return the specified string builder
*/
public static String intervalToString(IntervalQualifier qualifier, boolean negative, long leading, long remaining)
{
StringBuilder buff = new StringBuilder().append("INTERVAL ");
buff.append('\'');
public static StringBuilder appendInterval(StringBuilder buff, IntervalQualifier qualifier, boolean negative,
long leading, long remaining) {
buff.append("INTERVAL '");
if (negative) {
buff.append('-');
}
......@@ -453,8 +455,7 @@ public class IntervalUtils {
appendSecondsWithNanos(buff, remaining);
break;
}
buff.append("' ").append(qualifier);
return buff.toString();
return buff.append("' ").append(qualifier);
}
private static void appendSecondsWithNanos(StringBuilder buff, long nanos) {
......
......@@ -155,7 +155,7 @@ public class NetUtils {
*/
private static InetAddress getBindAddress() throws UnknownHostException {
String host = SysProperties.BIND_ADDRESS;
if (host == null || host.length() == 0) {
if (host == null || host.isEmpty()) {
return null;
}
synchronized (NetUtils.class) {
......
......@@ -362,13 +362,14 @@ public class ToChar {
}
int i = idx + 1;
boolean allZeroes = true;
for (; i < numberStr.length(); i++) {
int length = numberStr.length();
for (; i < length; i++) {
if (numberStr.charAt(i) != '0') {
allZeroes = false;
break;
}
}
final char[] zeroes = new char[allZeroes ? numberStr.length() - idx - 1: i - 1 - idx];
final char[] zeroes = new char[allZeroes ? length - idx - 1: i - 1 - idx];
Arrays.fill(zeroes, '0');
return String.valueOf(zeroes);
}
......@@ -688,7 +689,7 @@ public class ToChar {
StringBuilder output = new StringBuilder();
boolean fillMode = true;
for (int i = 0; i < format.length();) {
for (int i = 0, length = format.length(); i < length;) {
Capitalization cap;
......
......@@ -249,7 +249,7 @@ public class ToDateParser {
}
private boolean hasToParseData() {
return formatStr.length() > 0;
return !formatStr.isEmpty();
}
private void removeFirstChar() {
......
......@@ -651,7 +651,7 @@ class ToDateTokenizer {
* @return the list of tokens, or {@code null}
*/
static List<FormatTokenEnum> getTokensInQuestion(String formatStr) {
if (formatStr != null && formatStr.length() > 0) {
if (formatStr != null && !formatStr.isEmpty()) {
char key = Character.toUpperCase(formatStr.charAt(0));
if (key >= 'A' && key <= 'Y') {
List<FormatTokenEnum>[] tokens = TOKENS;
......
......@@ -222,12 +222,13 @@ public class CompareMode implements Comparator<Value> {
} else if (name.startsWith(CHARSET)) {
return new CharsetCollator(Charset.forName(name.substring(CHARSET.length())));
}
if (name.length() == 2) {
int length = name.length();
if (length == 2) {
Locale locale = new Locale(StringUtils.toLowerEnglish(name), "");
if (compareLocaleNames(locale, name)) {
result = Collator.getInstance(locale);
}
} else if (name.length() == 5) {
} else if (length == 5) {
// LL_CC (language_country)
int idx = name.indexOf('_');
if (idx >= 0) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论