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

Add IndexColumn.writeColumns()

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