提交 5b8a5307 authored 作者: Thomas Mueller's avatar Thomas Mueller

--no commit message

--no commit message
上级 79ba7f42
......@@ -5,147 +5,61 @@
package org.h2.engine;
import java.sql.SQLException;
import org.h2.command.Parser;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.table.Table;
import org.h2.util.ObjectArray;
/**
* @author Thomas
*/
public interface DbObject {
public static final int INDEX = 1;
public static final int SEQUENCE = 3;
public static final int TABLE_OR_VIEW = 0;
public static final int TRIGGER = 4;
public static final int USER = 2;
public static final int CONSTRAINT = 5;
public static final int FUNCTION_ALIAS = 9;
public static final int RIGHT = 8;
public static final int ROLE = 7;
public static final int SETTING = 6;
public static final int CONSTANT = 11;
public static final int SCHEMA = 10;
public static final int COMMENT = 13;
public static final int USER_DATATYPE = 12;
public abstract void setModified();
public abstract long getModificationId();
public abstract String getSQL();
public abstract class DbObject {
public static final int TABLE_OR_VIEW=0, INDEX=1, USER=2, SEQUENCE=3, TRIGGER=4;
public static final int CONSTRAINT = 5, SETTING = 6, ROLE = 7, RIGHT = 8, FUNCTION_ALIAS = 9;
public static final int SCHEMA = 10, CONSTANT = 11;
public static final int USER_DATATYPE = 12, COMMENT = 13;
private int id;
protected Database database;
protected Trace trace;
private String objectName;
private long modificationId;
private boolean temporary;
protected String comment;
protected DbObject(Database database, int id, String name, String traceModule) {
this.database = database;
this.trace = database.getTrace(traceModule);
this.id = id;
this.objectName = name;
this.modificationId = database.getModificationMetaId();
}
public void setModified() {
this.modificationId = database == null ? -1 : database.getNextModificationMetaId();
}
public long getModificationId() {
return modificationId;
}
protected void setObjectName(String name) {
objectName = name;
}
public String getSQL() {
return Parser.quoteIdentifier(objectName);
}
public ObjectArray getChildren() {
return null;
}
public Database getDatabase() {
return database;
}
public int getId() {
return id;
}
public String getName() {
return objectName;
}
public abstract ObjectArray getChildren();
public abstract Database getDatabase();
public abstract int getId();
public abstract String getName();
public abstract String getCreateSQLForCopy(Table table, String quotedName);
public abstract String getCreateSQL();
public abstract String getDropSQL();
public abstract int getType();
public abstract void removeChildrenAndResources(Session session) throws SQLException;
public abstract void removeChildrenAndResources(Session session)
throws SQLException;
public abstract void checkRename() throws SQLException;
protected void invalidate() {
setModified();
id = -1;
database = null;
trace = null;
objectName = null;
}
protected int getHeadPos() {
return 0;
}
public void rename(String newName) throws SQLException {
checkRename();
objectName = newName;
setModified();
}
public boolean getTemporary() {
return temporary;
}
public void setTemporary(boolean temporary) {
this.temporary = temporary;
}
public void setComment(String comment) {
this.comment = comment;
}
public String getComment() {
return comment;
}
static int getCreateOrder(int type) {
switch(type) {
case SETTING:
return 0;
case USER:
return 1;
case SCHEMA:
return 2;
case USER_DATATYPE:
return 3;
case SEQUENCE:
return 4;
case CONSTANT:
return 5;
case FUNCTION_ALIAS:
return 6;
case TABLE_OR_VIEW:
return 7;
case INDEX:
return 8;
case CONSTRAINT:
return 9;
case TRIGGER:
return 10;
case ROLE:
return 11;
case RIGHT:
return 12;
case COMMENT:
return 13;
default:
throw Message.getInternalError("type="+type);
}
}
}
public abstract void rename(String newName) throws SQLException;
public abstract boolean getTemporary();
public abstract void setTemporary(boolean temporary);
public abstract void setComment(String comment);
public abstract String getComment();
public abstract int getHeadPos();
}
\ No newline at end of file
......@@ -5,237 +5,68 @@
package org.h2.index;
import java.sql.SQLException;
import org.h2.constant.ErrorCode;
import org.h2.engine.Constants;
import org.h2.engine.DbObject;
import org.h2.engine.Session;
import org.h2.message.Message;
import org.h2.message.Trace;
import org.h2.result.Row;
import org.h2.result.SearchRow;
import org.h2.schema.SchemaObject;
import org.h2.table.Column;
import org.h2.table.Table;
import org.h2.util.StringUtils;
import org.h2.value.Value;
import org.h2.value.ValueNull;
/**
* @author Thomas
*/
public abstract class Index extends SchemaObject {
public interface Index extends SchemaObject {
protected Column[] columns;
protected int[] columnIndex;
protected Table table;
public IndexType indexType;
public static final int EMPTY_HEAD = -1;
protected long rowCount;
public Index(Table table, int id, String name, Column[] columns, IndexType indexType) {
super(table.getSchema(), id, name, Trace.INDEX);
this.indexType = indexType;
this.table = table;
if(columns != null) {
this.columns = columns;
columnIndex = new int[columns.length];
for(int i=0; i<columns.length; i++) {
columnIndex[i] = columns[i].getColumnId();
}
}
}
public String getDropSQL() {
return null;
}
public SQLException getDuplicateKeyException() {
StringBuffer buff = new StringBuffer();
buff.append(getName());
buff.append(" ");
buff.append(" ON ");
buff.append(table.getSQL());
buff.append("(");
buff.append(getColumnListSQL());
buff.append(")");
return Message.getSQLException(ErrorCode.DUPLICATE_KEY_1, buff.toString());
}
public String getPlanSQL() {
return getSQL();
}
public void removeChildrenAndResources(Session session) throws SQLException {
table.removeIndex(this);
remove(session);
}
public abstract SQLException getDuplicateKeyException();
public abstract String getPlanSQL();
public abstract void close(Session session) throws SQLException;
public abstract void add(Session session, Row row) throws SQLException;
public abstract void remove(Session session, Row row) throws SQLException;
public abstract Cursor find(Session session, SearchRow first, SearchRow last) throws SQLException;
public abstract double getCost(Session session, int[] masks) throws SQLException;
public abstract Cursor find(Session session, SearchRow first, SearchRow last)
throws SQLException;
public abstract double getCost(Session session, int[] masks)
throws SQLException;
public abstract void remove(Session session) throws SQLException;
public abstract void truncate(Session session) throws SQLException;
public abstract boolean canGetFirstOrLast(boolean first);
public abstract Value findFirstOrLast(Session session, boolean first) throws SQLException;
public abstract SearchRow findFirstOrLast(Session session, boolean first)
throws SQLException;
public abstract boolean needRebuild();
public long getRowCount() {
return rowCount;
}
public int getLookupCost(long rowCount) {
return 2;
}
public long getCostRangeIndex(int[] masks, long rowCount) throws SQLException {
rowCount += Constants.COST_ROW_OFFSET;
long cost = rowCount;
int totalSelectivity = 0;
for (int i = 0; masks != null && i < columns.length; i++) {
Column column = columns[i];
int index = column.getColumnId();
int mask = masks[index];
if ((mask & IndexCondition.EQUALITY) == IndexCondition.EQUALITY) {
if(i == columns.length-1 && getIndexType().isUnique()) {
cost = getLookupCost(rowCount) + 1;
break;
}
totalSelectivity = 100 - ((100-totalSelectivity) * (100-column.getSelectivity()) / 100);
long distinctRows = rowCount * totalSelectivity / 100;
if(distinctRows <= 0) {
distinctRows = 1;
}
long rowsSelected = rowCount / distinctRows;
if(rowsSelected < 1) {
rowsSelected = 1;
}
cost = getLookupCost(rowCount) + rowsSelected;
} else if ((mask & IndexCondition.RANGE) == IndexCondition.RANGE) {
cost = getLookupCost(rowCount) + rowCount / 4;
break;
} else if ((mask & IndexCondition.START) == IndexCondition.START) {
cost = getLookupCost(rowCount) + rowCount / 3;
break;
} else if ((mask & IndexCondition.END) == IndexCondition.END) {
cost = rowCount / 3;
break;
} else {
break;
}
}
return cost;
}
public int compareRows(SearchRow rowData, SearchRow compare) throws SQLException {
for (int i = 0; i < columns.length; i++) {
int index = columnIndex[i];
Value v = compare.getValue(index);
if(v==null) {
// can't compare further
return 0;
}
int c = compareValues(rowData.getValue(index), v);
if (c != 0) {
return c;
}
}
return 0;
}
public boolean isNull(Row newRow) {
for (int i = 0; i < columns.length; i++) {
int index = columnIndex[i];
Value v = newRow.getValue(index);
if(v == ValueNull.INSTANCE) {
return true;
}
}
return false;
}
public int compareKeys(SearchRow rowData, SearchRow compare) {
int k1 = rowData.getPos();
int k2 = compare.getPos();
if (k1 == k2) {
return 0;
}
return k1 > k2 ? 1 : -1;
}
private int compareValues(Value v1, Value v2) throws SQLException {
if (v1 == null) {
if (v2 == null) {
return 0;
}
return 1;
}
if (v2 == null) {
return -1;
}
return database.compareTypeSave(v1, v2);
}
public int getColumnIndex(Column col) {
for (int i = 0; i < columns.length; i++) {
if (columns[i] == col) {
return i;
}
}
return -1;
}
public String getColumnListSQL() {
StringBuffer buff = new StringBuffer();
for (int i = 0; i < columns.length; i++) {
if (i > 0) {
buff.append(", ");
}
buff.append(columns[i].getSQL());
}
return buff.toString();
}
public String getCreateSQLForCopy(Table table, String quotedName) {
StringBuffer buff = new StringBuffer();
buff.append("CREATE ");
buff.append(indexType.getSQL());
if(!indexType.isPrimaryKey()) {
buff.append(' ');
buff.append(quotedName);
}
buff.append(" ON ");
buff.append(table.getSQL());
if(comment != null) {
buff.append(" COMMENT ");
buff.append(StringUtils.quoteStringSQL(comment));
}
buff.append("(");
buff.append(getColumnListSQL());
buff.append(")");
return buff.toString();
}
public String getCreateSQL() {
return getCreateSQLForCopy(table, getSQL());
}
public Column[] getColumns() {
return columns;
}
public IndexType getIndexType() {
return indexType;
}
public int getType() {
return DbObject.INDEX;
}
public Table getTable() {
return table;
}
}
public abstract long getRowCount(Session session);
public abstract int getLookupCost(long rowCount);
public abstract long getCostRangeIndex(int[] masks, long rowCount)
throws SQLException;
public abstract int compareRows(SearchRow rowData, SearchRow compare)
throws SQLException;
public abstract boolean isNull(Row newRow);
public abstract int compareKeys(SearchRow rowData, SearchRow compare);
public abstract int getColumnIndex(Column col);
public abstract String getColumnListSQL();
public abstract Column[] getColumns();
public abstract IndexType getIndexType();
public abstract Table getTable();
public abstract void commit(Row row) throws SQLException;
}
\ No newline at end of file
......@@ -6,7 +6,6 @@ package org.h2.schema;
import java.sql.SQLException;
import java.util.HashMap;
import org.h2.constant.ErrorCode;
import org.h2.constant.SysProperties;
import org.h2.constraint.Constraint;
......@@ -16,7 +15,6 @@ import org.h2.engine.DbObject;
import org.h2.engine.DbObjectBase;
import org.h2.engine.Session;
import org.h2.engine.User;
import org.h2.index.BaseIndex;
import org.h2.index.Index;
import org.h2.jdbc.JdbcSQLException;
import org.h2.message.Message;
......
......@@ -6,21 +6,8 @@ package org.h2.schema;
import org.h2.engine.DbObject;
public abstract class SchemaObject extends DbObject {
public interface SchemaObject extends DbObject {
public abstract Schema getSchema();
private Schema schema;
protected SchemaObject(Schema schema, int id, String name, String traceModule) {
super(schema.getDatabase(), id, name, traceModule);
this.schema = schema;
}
public Schema getSchema() {
return schema;
}
public String getSQL() {
return schema.getSQL() + "." + super.getSQL();
}
}
public abstract String getSQL();
}
\ No newline at end of file
......@@ -94,15 +94,20 @@ java -Xmx512m -Xrunhprof:cpu=samples,depth=8 org.h2.tools.RunScript -url jdbc:h2
/*
table with constraint
alter the table
add data
-> object is closed
CREATE TABLE TEST(ID INT, PARENT INT, CONSTRAINT A FOREIGN KEY(PARENT) REFERENCES(ID));
ALTER TABLE TEST ALTER COLUMN PARENT BIGINT;
INSERT INTO TEST VALUES(1, 1, 1);
CREATE TABLE Parent(ID INT PRIMARY KEY, Name VARCHAR);
CREATE TABLE Child(ID INT, P INT, PRIMARY KEY(ID, P));
ALTER TABLE Child ADD FOREIGN KEY(ID) REFERENCES Parent(ID);
ALTER TABLE Child ADD FOREIGN KEY(P) REFERENCES Parent(ID);
INSERT INTO Parent VALUES(1, '0'), (2, '0'), (3, '0');
INSERT INTO Child VALUES(2, 1);
ALTER TABLE Parent ALTER COLUMN Name BOOLEAN NULL;
DELETE FROM Parent WHERE ID=3;
DROP TABLE Parent, Child;
only admins can use nested tables:
CREATE USER TEST PASSWORD 'TEST';
SELECT * FROM (SELECT * FROM DUAL);
add MVCC
......
--- special grammar and test cases ---------------------------------------------------------------------------------------------
set autocommit false;
> ok
CREATE TABLE A(ID INT PRIMARY KEY, SK INT);
> ok
......@@ -32,6 +35,9 @@ ALTER TABLE A SET REFERENTIAL_INTEGRITY TRUE CHECK;
DROP TABLE A;
> ok
set autocommit true;
> ok
CREATE TABLE PARENT(ID INT);
> ok
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论