📄 tabledata.java
字号:
if (old == 0) {
row.setSessionId(newId);
} else if (old != newId) {
throw Message.getSQLException(ErrorCode.CONCURRENT_UPDATE_1, getName());
}
}
int i = indexes.size() - 1;
try {
for (; i >= 0; i--) {
Index index = (Index) indexes.get(i);
index.remove(session, row);
checkRowCount(session, index, -1);
}
rowCount--;
} catch (Throwable e) {
try {
while (++i < indexes.size()) {
Index index = (Index) indexes.get(i);
index.add(session, row);
checkRowCount(session, index, 0);
}
} catch (SQLException e2) {
// this could happen, for example on failure in the storage
// but if that is not the case it means there is something wrong
// with the database
// TODO log this problem
throw e2;
}
throw Message.convert(e);
}
}
public void truncate(Session session) throws SQLException {
lastModificationId = database.getNextModificationDataId();
for (int i = indexes.size() - 1; i >= 0; i--) {
Index index = (Index) indexes.get(i);
index.truncate(session);
if (SysProperties.CHECK) {
long rc = index.getRowCount(session);
if (rc != 0) {
throw Message.getInternalError("rowCount expected 0 got " + rc);
}
}
}
rowCount = 0;
}
public boolean isLockExclusive(Session s) {
return lockExclusive == s;
}
public void lock(Session session, boolean exclusive, boolean force) throws SQLException {
int lockMode = database.getLockMode();
if (lockMode == Constants.LOCK_MODE_OFF) {
return;
}
long max = System.currentTimeMillis() + session.getLockTimeout();
if (!force && database.isMultiVersion()) {
// MVCC: update, delete, and insert use a shared lock
// select doesn't lock
if (exclusive) {
exclusive = false;
} else {
return;
}
}
synchronized (database) {
while (true) {
if (lockExclusive == session) {
return;
}
if (exclusive) {
if (lockExclusive == null) {
if (lockShared.isEmpty()) {
traceLock(session, exclusive, "added for");
session.addLock(this);
lockExclusive = session;
return;
} else if (lockShared.size() == 1 && lockShared.contains(session)) {
traceLock(session, exclusive, "add (upgraded) for ");
lockExclusive = session;
return;
}
}
} else {
if (lockExclusive == null) {
if (lockMode == Constants.LOCK_MODE_READ_COMMITTED && !database.getMultiThreaded() && !database.isMultiVersion()) {
// READ_COMMITTED read locks are acquired but they
// are released immediately
// when allowing only one thread, no read locks are
// required
return;
} else if (!lockShared.contains(session)) {
traceLock(session, exclusive, "ok");
session.addLock(this);
lockShared.add(session);
}
return;
}
}
long now = System.currentTimeMillis();
if (now >= max) {
traceLock(session, exclusive, "timeout after " + session.getLockTimeout());
throw Message.getSQLException(ErrorCode.LOCK_TIMEOUT_1, getName());
}
try {
traceLock(session, exclusive, "waiting for");
if (database.getLockMode() == Constants.LOCK_MODE_TABLE_GC) {
for (int i = 0; i < 20; i++) {
long free = Runtime.getRuntime().freeMemory();
System.gc();
long free2 = Runtime.getRuntime().freeMemory();
if (free == free2) {
break;
}
}
}
database.wait(max - now);
} catch (InterruptedException e) {
// ignore
}
}
}
}
private void traceLock(Session session, boolean exclusive, String s) {
if (traceLock.debug()) {
traceLock.debug(session.getId() + " " + (exclusive ? "exclusive write lock" : "shared read lock") + " " + s + " " + getName());
}
}
public String getDropSQL() {
return "DROP TABLE IF EXISTS " + getSQL();
}
public String getCreateSQL() {
StringBuffer buff = new StringBuffer();
buff.append("CREATE ");
if (getTemporary()) {
if (globalTemporary) {
buff.append("GLOBAL ");
} else {
buff.append("LOCAL ");
}
buff.append("TEMPORARY ");
} else if (isPersistent()) {
buff.append("CACHED ");
} else {
buff.append("MEMORY ");
}
buff.append("TABLE ");
buff.append(getSQL());
if (comment != null) {
buff.append(" COMMENT ");
buff.append(StringUtils.quoteStringSQL(comment));
}
buff.append("(\n ");
for (int i = 0; i < columns.length; i++) {
Column column = columns[i];
if (i > 0) {
buff.append(",\n ");
}
buff.append(column.getCreateSQL());
}
buff.append("\n)");
return buff.toString();
}
public boolean isLockedExclusively() {
return lockExclusive != null;
}
public void unlock(Session s) {
if (database != null) {
traceLock(s, lockExclusive == s, "unlock");
if (lockExclusive == s) {
lockExclusive = null;
}
if (lockShared.size() > 0) {
lockShared.remove(s);
}
// TODO lock: maybe we need we fifo-queue to make sure nobody
// starves. check what other databases do
synchronized (database) {
if (database.getSessionCount() > 1) {
database.notifyAll();
}
}
}
}
public Record read(Session session, DataPage s) throws SQLException {
int len = s.readInt();
Value[] data = new Value[len];
for (int i = 0; i < len; i++) {
data[i] = s.readValue();
}
Row row = new Row(data, memoryPerRow);
return row;
}
public void setRowCount(int count) {
this.rowCount = count;
}
public void removeChildrenAndResources(Session session) throws SQLException {
super.removeChildrenAndResources(session);
// go backwards because database.removeIndex will call table.removeIndex
while (indexes.size() > 1) {
Index index = (Index) indexes.get(1);
if (index.getName() != null) {
database.removeSchemaObject(session, index);
}
}
if (SysProperties.CHECK) {
ObjectArray list = database.getAllSchemaObjects(DbObject.INDEX);
for (int i = 0; i < list.size(); i++) {
Index index = (Index) list.get(i);
if (index.getTable() == this) {
throw Message.getInternalError("index not dropped: " + index.getName());
}
}
}
scanIndex.remove(session);
database.removeMeta(session, getId());
scanIndex = null;
lockExclusive = null;
lockShared = null;
invalidate();
}
public void checkRename() throws SQLException {
}
public void checkSupportAlter() throws SQLException {
}
public boolean canTruncate() {
ObjectArray constraints = getConstraints();
for (int i = 0; constraints != null && i < constraints.size(); i++) {
Constraint c = (Constraint) constraints.get(i);
if (!(c.getConstraintType().equals(Constraint.REFERENTIAL))) {
continue;
}
ConstraintReferential ref = (ConstraintReferential) c;
if (ref.getRefTable() == this) {
return false;
}
}
return true;
}
public String getTableType() {
return Table.TABLE;
}
public void setGlobalTemporary(boolean globalTemporary) {
this.globalTemporary = globalTemporary;
}
public boolean getGlobalTemporary() {
return globalTemporary;
}
public long getMaxDataModificationId() {
return lastModificationId;
}
public boolean isClustered() {
return clustered;
}
public boolean getContainsLargeObject() {
return containsLargeObject;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -