提交 10ce4998 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Add IndexColumn.writeColumns()

上级 15609e26
...@@ -8,7 +8,6 @@ package org.h2.constraint; ...@@ -8,7 +8,6 @@ package org.h2.constraint;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser;
import org.h2.command.Prepared; import org.h2.command.Prepared;
import org.h2.engine.Session; import org.h2.engine.Session;
import org.h2.expression.Expression; import org.h2.expression.Expression;
...@@ -23,7 +22,6 @@ import org.h2.schema.Schema; ...@@ -23,7 +22,6 @@ import org.h2.schema.Schema;
import org.h2.table.Column; import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.Value; import org.h2.value.Value;
import org.h2.value.ValueNull; import org.h2.value.ValueNull;
...@@ -79,53 +77,46 @@ public class ConstraintReferential extends Constraint { ...@@ -79,53 +77,46 @@ public class ConstraintReferential extends Constraint {
*/ */
public String getCreateSQLForCopy(Table forTable, Table forRefTable, public String getCreateSQLForCopy(Table forTable, Table forRefTable,
String quotedName, boolean internalIndex) { String quotedName, boolean internalIndex) {
StatementBuilder buff = new StatementBuilder("ALTER TABLE "); StringBuilder builder = new StringBuilder("ALTER TABLE ");
forTable.getSQL(buff.builder()).append(" ADD CONSTRAINT "); forTable.getSQL(builder).append(" ADD CONSTRAINT ");
if (forTable.isHidden()) { if (forTable.isHidden()) {
buff.append("IF NOT EXISTS "); builder.append("IF NOT EXISTS ");
} }
buff.append(quotedName); builder.append(quotedName);
if (comment != null) { if (comment != null) {
buff.append(" COMMENT "); builder.append(" COMMENT ");
StringUtils.quoteStringSQL(buff.builder(), comment); StringUtils.quoteStringSQL(builder, comment);
} }
IndexColumn[] cols = columns; IndexColumn[] cols = columns;
IndexColumn[] refCols = refColumns; IndexColumn[] refCols = refColumns;
buff.append(" FOREIGN KEY("); builder.append(" FOREIGN KEY(");
for (IndexColumn c : cols) { IndexColumn.writeColumns(builder, cols);
buff.appendExceptFirst(", "); builder.append(')');
buff.append(c.getSQL());
}
buff.append(')');
if (internalIndex && indexOwner && forTable == this.table) { if (internalIndex && indexOwner && forTable == this.table) {
buff.append(" INDEX "); builder.append(" INDEX ");
index.getSQL(buff.builder()); index.getSQL(builder);
} }
buff.append(" REFERENCES "); builder.append(" REFERENCES ");
if (this.table == this.refTable) { if (this.table == this.refTable) {
// self-referencing constraints: need to use new table // self-referencing constraints: need to use new table
forTable.getSQL(buff.builder()); forTable.getSQL(builder);
} else { } else {
forRefTable.getSQL(buff.builder()); forRefTable.getSQL(builder);
}
buff.append('(');
buff.resetCount();
for (IndexColumn r : refCols) {
buff.appendExceptFirst(", ");
buff.append(r.getSQL());
} }
buff.append(')'); builder.append('(');
IndexColumn.writeColumns(builder, refCols);
builder.append(')');
if (internalIndex && refIndexOwner && forTable == this.table) { if (internalIndex && refIndexOwner && forTable == this.table) {
buff.append(" INDEX "); builder.append(" INDEX ");
refIndex.getSQL(buff.builder()); refIndex.getSQL(builder);
} }
if (deleteAction != ConstraintActionType.RESTRICT) { if (deleteAction != ConstraintActionType.RESTRICT) {
buff.append(" ON DELETE ").append(deleteAction.getSqlName()); builder.append(" ON DELETE ").append(deleteAction.getSqlName());
} }
if (updateAction != ConstraintActionType.RESTRICT) { if (updateAction != ConstraintActionType.RESTRICT) {
buff.append(" ON UPDATE ").append(updateAction.getSqlName()); builder.append(" ON UPDATE ").append(updateAction.getSqlName());
} }
return buff.append(" NOCHECK").toString(); return builder.append(" NOCHECK").toString();
} }
...@@ -138,35 +129,28 @@ public class ConstraintReferential extends Constraint { ...@@ -138,35 +129,28 @@ public class ConstraintReferential extends Constraint {
* @return the description * @return the description
*/ */
private String getShortDescription(Index searchIndex, SearchRow check) { private String getShortDescription(Index searchIndex, SearchRow check) {
StatementBuilder buff = new StatementBuilder(getName()); StringBuilder builder = new StringBuilder(getName()).append(": ");
buff.append(": "); table.getSQL(builder).append(" FOREIGN KEY(");
table.getSQL(buff.builder()).append(" FOREIGN KEY("); IndexColumn.writeColumns(builder, columns);
for (IndexColumn c : columns) { builder.append(") REFERENCES ");
buff.appendExceptFirst(", "); refTable.getSQL(builder).append('(');
buff.append(c.getSQL()); IndexColumn.writeColumns(builder, refColumns);
} builder.append(')');
buff.append(") REFERENCES ");
refTable.getSQL(buff.builder()).append('(');
buff.resetCount();
for (IndexColumn r : refColumns) {
buff.appendExceptFirst(", ");
buff.append(r.getSQL());
}
buff.append(')');
if (searchIndex != null && check != null) { if (searchIndex != null && check != null) {
buff.append(" ("); builder.append(" (");
buff.resetCount();
Column[] cols = searchIndex.getColumns(); Column[] cols = searchIndex.getColumns();
int len = Math.min(columns.length, cols.length); int len = Math.min(columns.length, cols.length);
for (int i = 0; i < len; i++) { for (int i = 0; i < len; i++) {
int idx = cols[i].getColumnId(); int idx = cols[i].getColumnId();
Value c = check.getValue(idx); Value c = check.getValue(idx);
buff.appendExceptFirst(", "); if (i > 0) {
buff.append(c == null ? "" : c.toString()); builder.append(", ");
}
builder.append(c == null ? "" : c.toString());
} }
buff.append(')'); builder.append(')');
} }
return buff.toString(); return builder.toString();
} }
@Override @Override
...@@ -491,15 +475,15 @@ public class ConstraintReferential extends Constraint { ...@@ -491,15 +475,15 @@ public class ConstraintReferential extends Constraint {
if (deleteAction == ConstraintActionType.RESTRICT) { if (deleteAction == ConstraintActionType.RESTRICT) {
return; return;
} }
StatementBuilder buff = new StatementBuilder(); StringBuilder builder = new StringBuilder();
if (deleteAction == ConstraintActionType.CASCADE) { if (deleteAction == ConstraintActionType.CASCADE) {
buff.append("DELETE FROM "); builder.append("DELETE FROM ");
table.getSQL(buff.builder()); table.getSQL(builder);
} else { } else {
appendUpdate(buff); appendUpdate(builder);
} }
appendWhere(buff); appendWhere(builder);
deleteSQL = buff.toString(); deleteSQL = builder.toString();
} }
private Prepared getUpdate(Session session) { private Prepared getUpdate(Session session) {
...@@ -534,10 +518,10 @@ public class ConstraintReferential extends Constraint { ...@@ -534,10 +518,10 @@ public class ConstraintReferential extends Constraint {
if (updateAction == ConstraintActionType.RESTRICT) { if (updateAction == ConstraintActionType.RESTRICT) {
return; return;
} }
StatementBuilder buff = new StatementBuilder(); StringBuilder builder = new StringBuilder();
appendUpdate(buff); appendUpdate(builder);
appendWhere(buff); appendWhere(builder);
updateSQL = buff.toString(); updateSQL = builder.toString();
} }
@Override @Override
...@@ -569,22 +553,24 @@ public class ConstraintReferential extends Constraint { ...@@ -569,22 +553,24 @@ public class ConstraintReferential extends Constraint {
return command; return command;
} }
private void appendUpdate(StatementBuilder buff) { private void appendUpdate(StringBuilder builder) {
buff.append("UPDATE "); builder.append("UPDATE ");
table.getSQL(buff.builder()).append(" SET "); table.getSQL(builder).append(" SET ");
buff.resetCount(); for (int i = 0, l = columns.length; i < l; i++) {
for (IndexColumn c : columns) { if (i > 0) {
buff.appendExceptFirst(", "); builder.append(", ");
c.column.getSQL(buff.builder()).append("=?"); }
columns[i].column.getSQL(builder).append("=?");
} }
} }
private void appendWhere(StatementBuilder buff) { private void appendWhere(StringBuilder builder) {
buff.append(" WHERE "); builder.append(" WHERE ");
buff.resetCount(); for (int i = 0, l = columns.length; i < l; i++) {
for (IndexColumn c : columns) { if (i > 0) {
buff.appendExceptFirst(" AND "); builder.append(" AND ");
c.column.getSQL(buff.builder()).append("=?"); }
columns[i].column.getSQL(builder).append("=?");
} }
} }
...@@ -621,36 +607,25 @@ public class ConstraintReferential extends Constraint { ...@@ -621,36 +607,25 @@ public class ConstraintReferential extends Constraint {
return; return;
} }
session.startStatementWithinTransaction(); session.startStatementWithinTransaction();
StatementBuilder buff = new StatementBuilder("SELECT 1 FROM (SELECT "); StringBuilder builder = new StringBuilder("SELECT 1 FROM (SELECT ");
for (IndexColumn c : columns) { IndexColumn.writeColumns(builder, columns);
buff.appendExceptFirst(", "); builder.append(" FROM ");
buff.append(c.getSQL()); table.getSQL(builder).append(" WHERE ");
} IndexColumn.writeColumns(builder, columns, " AND ", " IS NOT NULL ");
buff.append(" FROM "); builder.append(" ORDER BY ");
table.getSQL(buff.builder()).append(" WHERE "); IndexColumn.writeColumns(builder, columns);
buff.resetCount(); builder.append(") C WHERE NOT EXISTS(SELECT 1 FROM ");
for (IndexColumn c : columns) { refTable.getSQL(builder).append(" P WHERE ");
buff.appendExceptFirst(" AND "); for (int i = 0, l = columns.length; i < l; i++) {
buff.append(c.getSQL()).append(" IS NOT NULL "); if (i > 0) {
} builder.append(" AND ");
buff.append(" ORDER BY "); }
buff.resetCount(); builder.append("C.");
for (IndexColumn c : columns) { columns[i].getSQL(builder).append('=').append("P.");
buff.appendExceptFirst(", "); refColumns[i].getSQL(builder);
buff.append(c.getSQL()); }
} builder.append(')');
buff.append(") C WHERE NOT EXISTS(SELECT 1 FROM "); ResultInterface r = session.prepare(builder.toString()).query(1);
refTable.getSQL(buff.builder()).append(" P WHERE ");
buff.resetCount();
int i = 0;
for (IndexColumn c : columns) {
buff.appendExceptFirst(" AND ");
buff.append("C.").append(c.getSQL()).append('=').
append("P.").append(refColumns[i++].getSQL());
}
buff.append(')');
String sql = buff.toString();
ResultInterface r = session.prepare(sql).query(1);
if (r.next()) { if (r.next()) {
throw DbException.get(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1, throw DbException.get(ErrorCode.REFERENTIAL_INTEGRITY_VIOLATED_PARENT_MISSING_1,
getShortDescription(null, null)); getShortDescription(null, null));
......
...@@ -21,7 +21,6 @@ import org.h2.table.Column; ...@@ -21,7 +21,6 @@ import org.h2.table.Column;
import org.h2.table.IndexColumn; import org.h2.table.IndexColumn;
import org.h2.table.Table; import org.h2.table.Table;
import org.h2.table.TableFilter; import org.h2.table.TableFilter;
import org.h2.util.StatementBuilder;
import org.h2.util.StringUtils; import org.h2.util.StringUtils;
import org.h2.value.DataType; import org.h2.value.DataType;
import org.h2.value.Value; import org.h2.value.Value;
...@@ -412,12 +411,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index { ...@@ -412,12 +411,7 @@ public abstract class BaseIndex extends SchemaObjectBase implements Index {
* @return the list of columns * @return the list of columns
*/ */
private String getColumnListSQL() { private String getColumnListSQL() {
StatementBuilder buff = new StatementBuilder(); return IndexColumn.writeColumns(new StringBuilder(), indexColumns).toString();
for (IndexColumn c : indexColumns) {
buff.appendExceptFirst(", ");
buff.append(c.getSQL());
}
return buff.toString();
} }
@Override @Override
......
...@@ -142,7 +142,8 @@ public class PageDataIndex extends PageIndex { ...@@ -142,7 +142,8 @@ public class PageDataIndex extends PageIndex {
StringBuilder builder = new StringBuilder("PRIMARY KEY ON "); StringBuilder builder = new StringBuilder("PRIMARY KEY ON ");
table.getSQL(builder); table.getSQL(builder);
if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) { if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) {
builder.append('(').append(indexColumns[mainIndexColumn].getSQL()).append(')'); builder.append('(');
indexColumns[mainIndexColumn].getSQL(builder).append(')');
} }
DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, builder.toString()); DbException e = DbException.get(ErrorCode.DUPLICATE_KEY_1, builder.toString());
e.setSource(this); e.setSource(this);
......
...@@ -119,7 +119,8 @@ public class MVPrimaryIndex extends BaseIndex { ...@@ -119,7 +119,8 @@ public class MVPrimaryIndex extends BaseIndex {
StringBuilder builder = new StringBuilder("PRIMARY KEY ON "); StringBuilder builder = new StringBuilder("PRIMARY KEY ON ");
table.getSQL(builder); table.getSQL(builder);
if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) { if (mainIndexColumn >= 0 && mainIndexColumn < indexColumns.length) {
builder.append('(').append(indexColumns[mainIndexColumn].getSQL()).append(')'); builder.append('(');
indexColumns[mainIndexColumn].getSQL(builder).append(')');
} }
int errorCode = ErrorCode.CONCURRENT_UPDATE_1; int errorCode = ErrorCode.CONCURRENT_UPDATE_1;
if (map.get(key) != null) { if (map.get(key) != null) {
......
...@@ -136,7 +136,7 @@ public class SortOrder implements Comparator<Value[]> { ...@@ -136,7 +136,7 @@ public class SortOrder implements Comparator<Value[]> {
/** /**
* Appends type information (DESC, NULLS FIRST, NULLS LAST) to the specified statement builder. * Appends type information (DESC, NULLS FIRST, NULLS LAST) to the specified statement builder.
* @param builder statement builder * @param builder string builder
* @param type sort type * @param type sort type
*/ */
public static void typeToString(StringBuilder builder, int type) { public static void typeToString(StringBuilder builder, int type) {
......
...@@ -30,15 +30,58 @@ public class IndexColumn { ...@@ -30,15 +30,58 @@ public class IndexColumn {
public int sortType = SortOrder.ASCENDING; public int sortType = SortOrder.ASCENDING;
/** /**
* Get the SQL snippet for this index column. * Appends the specified columns to the specified builder.
* *
* @return the SQL snippet * @param builder
* string builder
* @param columns
* index columns
* @return the specified string builder
*/ */
public String getSQL() { public static StringBuilder writeColumns(StringBuilder builder, IndexColumn[] columns) {
StringBuilder builder = new StringBuilder(); for (int i = 0, l = columns.length; i < l; i++) {
column.getSQL(builder); if (i > 0) {
SortOrder.typeToString(builder, sortType); builder.append(", ");
return builder.toString(); }
columns[i].getSQL(builder);
}
return builder;
}
/**
* Appends the specified columns to the specified builder.
*
* @param builder
* string builder
* @param columns
* index columns
* @param separator
* separator
* @param suffix
* additional SQL to append after each column
* @return the specified string builder
*/
public static StringBuilder writeColumns(StringBuilder builder, IndexColumn[] columns, String separator,
String suffix) {
for (int i = 0, l = columns.length; i < l; i++) {
if (i > 0) {
builder.append(separator);
}
columns[i].getSQL(builder).append(suffix);
}
return builder;
}
/**
* Appends the SQL snippet for this index column to the specified string builder.
*
* @param builder
* string builder
* @return the specified string builder
*/
public StringBuilder getSQL(StringBuilder builder) {
SortOrder.typeToString(column.getSQL(builder), sortType);
return builder;
} }
/** /**
...@@ -71,6 +114,6 @@ public class IndexColumn { ...@@ -71,6 +114,6 @@ public class IndexColumn {
@Override @Override
public String toString() { public String toString() {
return "IndexColumn " + getSQL(); return getSQL(new StringBuilder("IndexColumn ")).toString();
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论