/* Copyright (c) 2001-2019, The HSQL Development Group
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of the HSQL Development Group nor the names of its
 * contributors may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


package org.hsqldb;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.hsqldb.HsqlNameManager.HsqlName;
import org.hsqldb.error.Error;
import org.hsqldb.error.ErrorCode;
import org.hsqldb.lib.HashMappedList;
import org.hsqldb.lib.HsqlArrayList;
import org.hsqldb.lib.Iterator;
import org.hsqldb.lib.MultiValueHashMap;
import org.hsqldb.lib.OrderedHashSet;
import org.hsqldb.lib.StringConverter;
import org.hsqldb.lib.WrapperIterator;
import org.hsqldb.navigator.RowIterator;
import org.hsqldb.rights.Grantee;
import org.hsqldb.types.Charset;
import org.hsqldb.types.Collation;
import org.hsqldb.types.Type;

Manages all SCHEMA related database objects
Author:Fred Toussi (fredt@users dot sourceforge.net)
Version:2.5.0
Since:1.8.0
/** * Manages all SCHEMA related database objects * * @author Fred Toussi (fredt@users dot sourceforge.net) * @version 2.5.0 * @since 1.8.0 */
public class SchemaManager { Database database; HsqlName defaultSchemaHsqlName; HashMappedList schemaMap = new HashMappedList(); MultiValueHashMap referenceMap = new MultiValueHashMap(); int defaultTableType = TableBase.MEMORY_TABLE; long schemaChangeTimestamp; HsqlName[] catalogNameArray; // ReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock writeLock = lock.writeLock(); // Table dualTable; public Table dataChangeTable; public SchemaManager(Database database) { this.database = database; defaultSchemaHsqlName = SqlInvariants.INFORMATION_SCHEMA_HSQLNAME; catalogNameArray = new HsqlName[]{ database.getCatalogName() }; Schema schema = new Schema(SqlInvariants.INFORMATION_SCHEMA_HSQLNAME, SqlInvariants.INFORMATION_SCHEMA_HSQLNAME.owner); schemaMap.put(schema.getName().name, schema); try { schema.charsetLookup.add(Charset.SQL_TEXT, false); schema.charsetLookup.add(Charset.SQL_IDENTIFIER_CHARSET, false); schema.charsetLookup.add(Charset.SQL_CHARACTER, false); schema.collationLookup.add(Collation.getDefaultInstance(), false); schema.collationLookup.add( Collation.getDefaultIgnoreCaseInstance(), false); schema.typeLookup.add(TypeInvariants.CARDINAL_NUMBER, false); schema.typeLookup.add(TypeInvariants.YES_OR_NO, false); schema.typeLookup.add(TypeInvariants.CHARACTER_DATA, false); schema.typeLookup.add(TypeInvariants.SQL_IDENTIFIER, false); schema.typeLookup.add(TypeInvariants.TIME_STAMP, false); schema.typeLookup.add(TypeInvariants.NCNAME, false); schema.typeLookup.add(TypeInvariants.URI, false); } catch (HsqlException e) {} } public void setSchemaChangeTimestamp() { schemaChangeTimestamp = database.txManager.getGlobalChangeTimestamp(); } public long getSchemaChangeTimestamp() { return schemaChangeTimestamp; } // pre-defined public HsqlName getSQLJSchemaHsqlName() { return SqlInvariants.SQLJ_SCHEMA_HSQLNAME; } // SCHEMA management public void createPublicSchema() { writeLock.lock(); try { HsqlName name = database.nameManager.newHsqlName(null, SqlInvariants.PUBLIC_SCHEMA, SchemaObject.SCHEMA); Schema schema = new Schema(name, database.getGranteeManager().getDBARole()); defaultSchemaHsqlName = schema.getName(); schemaMap.put(schema.getName().name, schema); } finally { writeLock.unlock(); } }
Creates a schema belonging to the given grantee.
/** * Creates a schema belonging to the given grantee. */
public void createSchema(HsqlName name, Grantee owner) { writeLock.lock(); try { SqlInvariants.checkSchemaNameNotSystem(name.name); Schema schema = new Schema(name, owner); schemaMap.add(name.name, schema); } finally { writeLock.unlock(); } } public void dropSchema(Session session, String name, boolean cascade) { writeLock.lock(); try { Schema schema = (Schema) schemaMap.get(name); if (schema == null) { throw Error.error(ErrorCode.X_42501, name); } if (SqlInvariants.isLobsSchemaName(name)) { throw Error.error(ErrorCode.X_42503, name); } if (!cascade && !schema.isEmpty()) { throw Error.error(ErrorCode.X_2B000); } OrderedHashSet externalReferences = new OrderedHashSet(); getCascadingReferencesToSchema(schema.getName(), externalReferences); removeSchemaObjects(externalReferences); Iterator tableIterator = schema.schemaObjectIterator(SchemaObject.TABLE); while (tableIterator.hasNext()) { Table table = ((Table) tableIterator.next()); Constraint[] list = table.getFKConstraints(); for (int i = 0; i < list.length; i++) { Constraint constraint = list[i]; if (constraint.getMain().getSchemaName() != schema.getName()) { constraint.getMain().removeConstraint( constraint.getMainName().name); removeReferencesFrom(constraint); } } removeTable(session, table); } Iterator sequenceIterator = schema.schemaObjectIterator(SchemaObject.SEQUENCE); while (sequenceIterator.hasNext()) { NumberSequence sequence = ((NumberSequence) sequenceIterator.next()); database.getGranteeManager().removeDbObject( sequence.getName()); } schema.release(); schemaMap.remove(name); if (defaultSchemaHsqlName.name.equals(name)) { schema = new Schema(defaultSchemaHsqlName, database.getGranteeManager().getDBARole()); defaultSchemaHsqlName = schema.getName(); schemaMap.put(schema.getName().name, schema); } else { HsqlName schemaName = schema.getName(); // these are called last and in this particular order database.getUserManager().removeSchemaReference(schemaName); database.getSessionManager().removeSchemaReference(schemaName); } } finally { writeLock.unlock(); } } public void renameSchema(HsqlName name, HsqlName newName) { writeLock.lock(); try { Schema schema = (Schema) schemaMap.get(name.name); Schema exists = (Schema) schemaMap.get(newName.name); if (schema == null) { throw Error.error(ErrorCode.X_42501, name.name); } if (exists != null) { throw Error.error(ErrorCode.X_42504, newName.name); } SqlInvariants.checkSchemaNameNotSystem(name.name); SqlInvariants.checkSchemaNameNotSystem(newName.name); int index = schemaMap.getIndex(name.name); schema.getName().rename(newName); schemaMap.set(index, newName.name, schema); } finally { writeLock.unlock(); } } public void release() { writeLock.lock(); try { Iterator it = schemaMap.values().iterator(); while (it.hasNext()) { Schema schema = (Schema) it.next(); schema.release(); } } finally { writeLock.unlock(); } } public String[] getSchemaNamesArray() { readLock.lock(); try { String[] array = new String[schemaMap.size()]; schemaMap.toKeysArray(array); return array; } finally { readLock.unlock(); } } public Schema[] getAllSchemas() { readLock.lock(); try { Schema[] objects = new Schema[schemaMap.size()]; schemaMap.toValuesArray(objects); return objects; } finally { readLock.unlock(); } } public HsqlName getUserSchemaHsqlName(String name) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(name); if (schema == null) { throw Error.error(ErrorCode.X_3F000, name); } if (schema.getName() == SqlInvariants.INFORMATION_SCHEMA_HSQLNAME) { throw Error.error(ErrorCode.X_3F000, name); } return schema.getName(); } finally { readLock.unlock(); } } public Grantee toSchemaOwner(String name) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(name); return schema == null ? null : schema.getOwner(); } finally { readLock.unlock(); } } public HsqlName getDefaultSchemaHsqlName() { return defaultSchemaHsqlName; } public void setDefaultSchemaHsqlName(HsqlName name) { defaultSchemaHsqlName = name; } public boolean schemaExists(String name) { readLock.lock(); try { return schemaMap.containsKey(name); } finally { readLock.unlock(); } } public HsqlName findSchemaHsqlName(String name) { readLock.lock(); try { Schema schema = ((Schema) schemaMap.get(name)); if (schema == null) { return null; } return schema.getName(); } finally { readLock.unlock(); } }
If schemaName is null, return the default schema name, else return the HsqlName object for the schema. If schemaName does not exist, throw.
/** * If schemaName is null, return the default schema name, else return * the HsqlName object for the schema. If schemaName does not exist, * throw. */
public HsqlName getSchemaHsqlName(String name) { if (name == null) { return defaultSchemaHsqlName; } readLock.lock(); try { Schema schema = ((Schema) schemaMap.get(name)); if (schema == null) { throw Error.error(ErrorCode.X_3F000, name); } return schema.getName(); } finally { readLock.unlock(); } }
Same as above, but return string
/** * Same as above, but return string */
public String getSchemaName(String name) { return getSchemaHsqlName(name).name; } public Schema findSchema(String name) { readLock.lock(); try { return ((Schema) schemaMap.get(name)); } finally { readLock.unlock(); } }
drop all schemas with the given authorisation
/** * drop all schemas with the given authorisation */
public void dropSchemas(Session session, Grantee grantee, boolean cascade) { writeLock.lock(); try { HsqlArrayList list = getSchemas(grantee); Iterator it = list.iterator(); while (it.hasNext()) { Schema schema = (Schema) it.next(); dropSchema(session, schema.getName().name, cascade); } } finally { writeLock.unlock(); } } public HsqlArrayList getSchemas(Grantee grantee) { readLock.lock(); try { HsqlArrayList list = new HsqlArrayList(); Iterator it = schemaMap.values().iterator(); while (it.hasNext()) { Schema schema = (Schema) it.next(); if (grantee.equals(schema.getOwner())) { list.add(schema); } } return list; } finally { readLock.unlock(); } } public boolean hasSchemas(Grantee grantee) { readLock.lock(); try { Iterator it = schemaMap.values().iterator(); while (it.hasNext()) { Schema schema = (Schema) it.next(); if (grantee.equals(schema.getOwner())) { return true; } } return false; } finally { readLock.unlock(); } }
Returns an HsqlArrayList containing references to all non-system tables and views. This includes all tables and views registered with this Database.
/** * Returns an HsqlArrayList containing references to all non-system * tables and views. This includes all tables and views registered with * this Database. */
public HsqlArrayList getAllTables(boolean withLobTables) { readLock.lock(); try { HsqlArrayList alltables = new HsqlArrayList(); String[] schemas = getSchemaNamesArray(); for (int i = 0; i < schemas.length; i++) { String name = schemas[i]; if (!withLobTables && SqlInvariants.isLobsSchemaName(name)) { continue; } if (SqlInvariants.isSystemSchemaName(name)) { continue; } HashMappedList current = getTables(name); alltables.addAll(current.values()); } return alltables; } finally { readLock.unlock(); } } public HashMappedList getTables(String schema) { readLock.lock(); try { Schema temp = (Schema) schemaMap.get(schema); return temp.tableList; } finally { readLock.unlock(); } } public HsqlName[] getCatalogNameArray() { return catalogNameArray; } public HsqlName[] getCatalogAndBaseTableNames() { readLock.lock(); try { OrderedHashSet names = new OrderedHashSet(); HsqlArrayList tables = getAllTables(false); for (int i = 0; i < tables.size(); i++) { Table table = (Table) tables.get(i); if (!table.isTemp()) { names.add(table.getName()); } } names.add(database.getCatalogName()); HsqlName[] array = new HsqlName[names.size()]; names.toArray(array); return array; } finally { readLock.unlock(); } } public HsqlName[] getCatalogAndBaseTableNames(HsqlName name) { if (name == null) { return catalogNameArray; } readLock.lock(); try { switch (name.type) { case SchemaObject.SCHEMA : { if (findSchemaHsqlName(name.name) == null) { return catalogNameArray; } OrderedHashSet names = new OrderedHashSet(); names.add(database.getCatalogName()); HashMappedList list = getTables(name.name); for (int i = 0; i < list.size(); i++) { names.add(((SchemaObject) list.get(i)).getName()); } HsqlName[] array = new HsqlName[names.size()]; names.toArray(array); return array; } case SchemaObject.GRANTEE : { return catalogNameArray; } case SchemaObject.INDEX : case SchemaObject.CONSTRAINT : default : } SchemaObject object = findSchemaObject(name.name, name.schema.name, name.type); if (object == null) { return catalogNameArray; } HsqlName parent = object.getName().parent; OrderedHashSet references = getReferencesTo(object.getName()); OrderedHashSet names = new OrderedHashSet(); names.add(database.getCatalogName()); if (parent != null) { SchemaObject parentObject = findSchemaObject(parent.name, parent.schema.name, parent.type); if (parentObject != null && parentObject.getName().type == SchemaObject.TABLE) { names.add(parentObject.getName()); } } if (object.getName().type == SchemaObject.TABLE) { names.add(object.getName()); } for (int i = 0; i < references.size(); i++) { HsqlName reference = (HsqlName) references.get(i); if (reference.type == SchemaObject.TABLE) { Table table = findUserTable(reference.name, reference.schema.name); if (table != null && !table.isTemp()) { names.add(reference); } } } HsqlName[] array = new HsqlName[names.size()]; names.toArray(array); return array; } finally { readLock.unlock(); } } private SchemaObjectSet getSchemaObjectSet(Schema schema, int type) { SchemaObjectSet set = null; switch (type) { case SchemaObject.SEQUENCE : set = schema.sequenceLookup; break; case SchemaObject.TABLE : case SchemaObject.VIEW : set = schema.tableLookup; break; case SchemaObject.CHARSET : set = schema.charsetLookup; break; case SchemaObject.COLLATION : set = schema.collationLookup; break; case SchemaObject.PROCEDURE : set = schema.procedureLookup; break; case SchemaObject.FUNCTION : set = schema.functionLookup; break; case SchemaObject.DOMAIN : case SchemaObject.TYPE : set = schema.typeLookup; break; case SchemaObject.INDEX : set = schema.indexLookup; break; case SchemaObject.CONSTRAINT : set = schema.constraintLookup; break; case SchemaObject.TRIGGER : set = schema.triggerLookup; break; case SchemaObject.SPECIFIC_ROUTINE : set = schema.specificRoutineLookup; break; case SchemaObject.REFERENCE : set = schema.referenceLookup; break; default : throw Error.runtimeError(ErrorCode.U_S0500, "SchemaObjectSet"); } return set; } public void checkSchemaObjectNotExists(HsqlName name) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(name.schema.name); SchemaObjectSet set = getSchemaObjectSet(schema, name.type); set.checkAdd(name); } finally { readLock.unlock(); } } public Table getUserTable(HsqlName name) { return getUserTable(name.name, name.schema.name); }
Returns the specified user-defined table or view visible within the context of the specified Session. Throws if the table does not exist in the context.
/** * Returns the specified user-defined table or view visible within the * context of the specified Session. * Throws if the table does not exist in the context. */
public Table getUserTable(String name, String schema) { Table t = findUserTable(name, schema); if (t == null) { String longName = schema == null ? name : schema + '.' + name; throw Error.error(ErrorCode.X_42501, longName); } return t; }
Returns the specified user-defined table or view visible within the context of the specified schema. It excludes system tables. Returns null if the table does not exist in the context.
/** * Returns the specified user-defined table or view visible within the * context of the specified schema. It excludes system tables. * Returns null if the table does not exist in the context. */
public Table findUserTable(String name, String schemaName) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema == null) { return null; } int i = schema.tableList.getIndex(name); if (i == -1) { return null; } return (Table) schema.tableList.get(i); } finally { readLock.unlock(); } }
Returns the specified session context table. Returns null if the table does not exist in the context.
/** * Returns the specified session context table. * Returns null if the table does not exist in the context. */
public Table findSessionTable(Session session, String name) { return session.sessionContext.findSessionTable(name); }
Drops the specified user-defined view or table from this Database object.

The process of dropping a table or view includes:

  1. checking that the specified Session's currently connected User has the right to perform this operation and refusing to proceed if not by throwing.
  2. checking for referential constraints that conflict with this operation and refusing to proceed if they exist by throwing.
  3. removing the specified Table from this Database object.
  4. removing any exported foreign keys Constraint objects held by any tables referenced by the table to be dropped. This is especially important so that the dropped Table ceases to be referenced, eventually allowing its full garbage collection.

Params:
  • session – the connected context in which to perform this operation
  • table – if true and if the Table to drop does not exist, fail silently, else throw
  • cascade – true if the name argument refers to a View
/** * Drops the specified user-defined view or table from this Database object. * * <p> The process of dropping a table or view includes: * <OL> * <LI> checking that the specified Session's currently connected User has * the right to perform this operation and refusing to proceed if not by * throwing. * <LI> checking for referential constraints that conflict with this * operation and refusing to proceed if they exist by throwing.</LI> * <LI> removing the specified Table from this Database object. * <LI> removing any exported foreign keys Constraint objects held by any * tables referenced by the table to be dropped. This is especially * important so that the dropped Table ceases to be referenced, eventually * allowing its full garbage collection. * <LI> * </OL> * * <p> * * @param session the connected context in which to perform this operation * @param table if true and if the Table to drop does not exist, fail * silently, else throw * @param cascade true if the name argument refers to a View */
public void dropTableOrView(Session session, Table table, boolean cascade) { writeLock.lock(); try { if (table.isView()) { dropView(table, cascade); } else { dropTable(session, table, cascade); } } finally { writeLock.unlock(); } } private void dropView(Table table, boolean cascade) { Schema schema = (Schema) schemaMap.get(table.getSchemaName().name); removeSchemaObject(table.getName(), cascade); removeTableDependentReferences(table); schema.triggerLookup.removeParent(table.getName()); } private void dropTable(Session session, Table table, boolean cascade) { Schema schema = (Schema) schemaMap.get(table.getSchemaName().name); OrderedHashSet externalConstraints = table.getDependentExternalConstraints(); OrderedHashSet externalReferences = new OrderedHashSet(); getCascadingReferencesTo(table.getName(), externalReferences); if (!cascade) { for (int i = 0; i < externalConstraints.size(); i++) { Constraint c = (Constraint) externalConstraints.get(i); HsqlName refname = c.getRefName(); if (c.getConstraintType() == SchemaObject.ConstraintTypes.MAIN) { throw Error.error( ErrorCode.X_42533, refname.getSchemaQualifiedStatementName()); } } if (!externalReferences.isEmpty()) { int i = 0; for (; i < externalReferences.size(); i++) { HsqlName name = (HsqlName) externalReferences.get(i); if (name.parent == table.getName()) { continue; } throw Error.error(ErrorCode.X_42502, name.getSchemaQualifiedStatementName()); } } } OrderedHashSet tableSet = new OrderedHashSet(); OrderedHashSet constraintNameSet = new OrderedHashSet(); OrderedHashSet indexNameSet = new OrderedHashSet(); for (int i = 0; i < externalConstraints.size(); i++) { Constraint c = (Constraint) externalConstraints.get(i); Table t = c.getMain(); if (t != table) { tableSet.add(t); } t = c.getRef(); if (t != table) { tableSet.add(t); } constraintNameSet.add(c.getMainName()); constraintNameSet.add(c.getRefName()); indexNameSet.add(c.getRefIndex().getName()); } OrderedHashSet uniqueConstraintNames = table.getUniquePKConstraintNames(); TableWorks tw = new TableWorks(session, table); tableSet = tw.dropConstraintsAndIndexes(tableSet, constraintNameSet, indexNameSet); tw.setNewTablesInSchema(tableSet); tw.updateConstraints(tableSet, constraintNameSet); removeSchemaObjects(externalReferences); removeTableDependentReferences(table); removeReferencesTo(uniqueConstraintNames); removeReferencesTo(table.getName()); removeReferencesFrom(table); schema.tableList.remove(table.getName().name); schema.indexLookup.removeParent(table.getName()); schema.constraintLookup.removeParent(table.getName()); schema.triggerLookup.removeParent(table.getName()); removeTable(session, table); recompileDependentObjects(tableSet); } private void removeTable(Session session, Table table) { database.getGranteeManager().removeDbObject(table.getName()); table.releaseTriggers(); if (!table.isView() && table.hasLobColumn()) { RowIterator it = table.rowIterator(session); while (it.next()) { Object[] data = it.getCurrent(); session.sessionData.adjustLobUsageCount(table, data, -1); } } if (table.tableType == TableBase.TEMP_TABLE) { Session[] sessions = database.sessionManager.getAllSessions(); for (int i = 0; i < sessions.length; i++) { sessions[i].sessionData.persistentStoreCollection.removeStore( table); } } else { database.persistentStoreCollection.removeStore(table); } } public void setTable(int index, Table table) { writeLock.lock(); try { Schema schema = (Schema) schemaMap.get(table.getSchemaName().name); schema.tableList.set(index, table.getName().name, table); } finally { writeLock.unlock(); } }
Returns index of a table or view in the HashMappedList that contains the table objects for this Database.
Params:
  • table – the Table object
Returns: the index of the specified table or view, or -1 if not found
/** * Returns index of a table or view in the HashMappedList that * contains the table objects for this Database. * * @param table the Table object * @return the index of the specified table or view, or -1 if not found */
public int getTableIndex(Table table) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(table.getSchemaName().name); if (schema == null) { return -1; } HsqlName name = table.getName(); return schema.tableList.getIndex(name.name); } finally { readLock.unlock(); } } public void recompileDependentObjects(OrderedHashSet tableSet) { writeLock.lock(); try { OrderedHashSet set = new OrderedHashSet(); for (int i = 0; i < tableSet.size(); i++) { Table table = (Table) tableSet.get(i); set.addAll(getReferencesTo(table.getName())); } Session session = database.sessionManager.getSysSession(); for (int i = 0; i < set.size(); i++) { HsqlName name = (HsqlName) set.get(i); switch (name.type) { case SchemaObject.VIEW : case SchemaObject.CONSTRAINT : case SchemaObject.ASSERTION : case SchemaObject.ROUTINE : case SchemaObject.PROCEDURE : case SchemaObject.FUNCTION : case SchemaObject.SPECIFIC_ROUTINE : case SchemaObject.TRIGGER : SchemaObject object = getSchemaObject(name); object.compile(session, null); break; default : } } if (Error.TRACE) { HsqlArrayList list = getAllTables(false); for (int i = 0; i < list.size(); i++) { Table t = (Table) list.get(i); t.verifyConstraintsIntegrity(); } } } finally { writeLock.unlock(); } }
After addition or removal of columns and indexes all views that reference the table should be recompiled.
/** * After addition or removal of columns and indexes all views that * reference the table should be recompiled. */
public void recompileDependentObjects(Table table) { writeLock.lock(); try { OrderedHashSet set = new OrderedHashSet(); getCascadingReferencesTo(table.getName(), set); Session session = database.sessionManager.getSysSession(); for (int i = 0; i < set.size(); i++) { HsqlName name = (HsqlName) set.get(i); switch (name.type) { case SchemaObject.VIEW : case SchemaObject.CONSTRAINT : case SchemaObject.ASSERTION : case SchemaObject.ROUTINE : case SchemaObject.PROCEDURE : case SchemaObject.FUNCTION : case SchemaObject.SPECIFIC_ROUTINE : case SchemaObject.TRIGGER : SchemaObject object = getSchemaObject(name); object.compile(session, null); break; default : } } if (Error.TRACE) { HsqlArrayList list = getAllTables(false); for (int i = 0; i < list.size(); i++) { Table t = (Table) list.get(i); t.verifyConstraintsIntegrity(); } } } finally { writeLock.unlock(); } } public Collation getCollation(Session session, String name, String schemaName) { Collation collation = null; if (schemaName == null || SqlInvariants.INFORMATION_SCHEMA.equals(schemaName)) { try { collation = Collation.getCollation(name); } catch (HsqlException e) {} } if (collation == null) { schemaName = session.getSchemaName(schemaName); collation = (Collation) getSchemaObject(name, schemaName, SchemaObject.COLLATION); } return collation; } public NumberSequence findSequence(Session session, String name, String schemaName) { NumberSequence seq = getSequence(name, session.getSchemaName(schemaName), false); if (seq == null && schemaName == null) { schemaName = session.getSchemaName(null); ReferenceObject ref = findSynonym(name, schemaName, SchemaObject.SEQUENCE); if (ref != null) { seq = getSequence(ref.target.name, ref.target.schema.name, false); } } return seq; } public NumberSequence getSequence(String name, String schemaName, boolean raise) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema != null) { NumberSequence object = (NumberSequence) schema.sequenceList.get(name); if (object != null) { return object; } } if (raise) { throw Error.error(ErrorCode.X_42501, name); } return null; } finally { readLock.unlock(); } } public Type getUserDefinedType(String name, String schemaName, boolean raise) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema != null) { SchemaObject object = schema.typeLookup.getObject(name); if (object != null) { return (Type) object; } } if (raise) { throw Error.error(ErrorCode.X_42501, name); } return null; } finally { readLock.unlock(); } } public Type findDomainOrUDT(Session session, String name, String prefix, String prePrefix, String prePrePrefix) { readLock.lock(); try { Type type = (Type) findSchemaObject(session, name, prefix, prePrefix, SchemaObject.TYPE); return type; } finally { readLock.unlock(); } } public Type getDomain(String name, String schemaName, boolean raise) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema != null) { SchemaObject object = schema.typeLookup.getObject(name); if (object != null && ((Type) object).isDomainType()) { return (Type) object; } } if (raise) { throw Error.error(ErrorCode.X_42501, name); } return null; } finally { readLock.unlock(); } } public Type getDistinctType(String name, String schemaName, boolean raise) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema != null) { SchemaObject object = schema.typeLookup.getObject(name); if (object != null && ((Type) object).isDistinctType()) { return (Type) object; } } if (raise) { throw Error.error(ErrorCode.X_42501, name); } return null; } finally { readLock.unlock(); } } public SchemaObject getSchemaObject(String name, String schemaName, int type) { readLock.lock(); try { SchemaObject object = findSchemaObject(name, schemaName, type); if (object == null) { throw Error.error(SchemaObjectSet.getGetErrorCode(type), name); } return object; } finally { readLock.unlock(); } } public SchemaObject getCharacterSet(Session session, String name, String schemaName) { if (schemaName == null || SqlInvariants.INFORMATION_SCHEMA.equals(schemaName)) { if (name.equals("SQL_IDENTIFIER")) { return Charset.SQL_IDENTIFIER_CHARSET; } if (name.equals("SQL_TEXT")) { return Charset.SQL_TEXT; } if (name.equals("LATIN1")) { return Charset.LATIN1; } if (name.equals("ASCII_GRAPHIC")) { return Charset.ASCII_GRAPHIC; } } if (schemaName == null) { schemaName = session.getSchemaName(null); } return getSchemaObject(name, schemaName, SchemaObject.CHARSET); } public Table findTable(Session session, String name, String prefix, String prePrefix) { Table t; if (prefix == null) { t = findSessionTable(session, name); if (t != null) { return t; } } if (prePrefix == null) { if (Tokens.T_SESSION.equals(prefix)) { t = findSessionTable(session, name); if (t != null) { return t; } } else if (SqlInvariants.INFORMATION_SCHEMA.equals(prefix) && database.dbInfo != null) { t = database.dbInfo.getSystemTable(session, name); if (t != null) { return t; } } } t = (Table) findSchemaObject(session, name, prefix, prePrefix, SchemaObject.TABLE); return t; } public SchemaObject findSchemaObject(Session session, String name, String prefix, String prePrefix, int type) { SchemaObject object; switch (type) { case SchemaObject.TABLE : case SchemaObject.ROUTINE : case SchemaObject.PROCEDURE : case SchemaObject.FUNCTION : case SchemaObject.TYPE : if (prefix == null) { if (session.database.sqlSyntaxOra || session.database.sqlSyntaxDb2 || session.isProcessingScript()) { if (type == SchemaObject.TABLE && Tokens.T_DUAL.equals(name)) { return dualTable; } } if (type == SchemaObject.TABLE) { // in future there will be a default module for // session tables and variables and anonymous // procedural sql blocks, which can eliminate this code Table t = findSessionTable(session, name); if (t != null) { return t; } } } else if (prePrefix == null) { if (type == SchemaObject.TABLE && Tokens.T_MODULE.equals(prefix)) { Table t = findSessionTable(session, name); if (t != null) { return t; } } if (type == SchemaObject.TABLE && Tokens.T_SESSION.equals(prefix)) { Table t = findSessionTable(session, name); if (t != null) { return t; } } } } if (prefix == null) { prefix = session.getSchemaName(null); } // catalog resolution here if (prePrefix != null && !prePrefix.equals(database.getCatalogName().name)) { return null; } if (type == SchemaObject.TABLE && SqlInvariants.INFORMATION_SCHEMA.equals(prefix) && database.dbInfo != null) { Table t = database.dbInfo.getSystemTable(session, name); if (t != null) { return t; } } return findSchemaObject(name, prefix, type); } public ReferenceObject findSynonym(String name, String schemaName, int type) { Schema schema = (Schema) schemaMap.get(schemaName); if (schema == null) { return null; } ReferenceObject reference = schema.findReference(name, type); return reference; } public SchemaObject findAnySchemaObjectForSynonym(String name, String schemaName) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema == null) { return null; } return schema.findAnySchemaObjectForSynonym(name); } finally { readLock.unlock(); } } public SchemaObject findSchemaObject(String name, String schemaName, int type) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); if (schema == null) { return null; } return schema.findSchemaObject(name, type); } finally { readLock.unlock(); } } // INDEX management
Returns the table that has an index with the given name and schema.
/** * Returns the table that has an index with the given name and schema. */
Table findUserTableForIndex(Session session, String name, String schemaName) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); HsqlName indexName = schema.indexLookup.getName(name); if (indexName == null) { return null; } return findUserTable(indexName.parent.name, schemaName); } finally { readLock.unlock(); } }
Drops the index with the specified name.
/** * Drops the index with the specified name. */
void dropIndex(Session session, HsqlName name) { writeLock.lock(); try { Table t = getUserTable(name.parent.name, name.parent.schema.name); TableWorks tw = new TableWorks(session, t); tw.dropIndex(name.name); } finally { writeLock.unlock(); } }
Drops the constraint with the specified name.
/** * Drops the constraint with the specified name. */
void dropConstraint(Session session, HsqlName name, boolean cascade) { writeLock.lock(); try { Table t = getUserTable(name.parent.name, name.parent.schema.name); TableWorks tw = new TableWorks(session, t); tw.dropConstraint(name.name, cascade); } finally { writeLock.unlock(); } } void removeDependentObjects(HsqlName name) { writeLock.lock(); try { Schema schema = (Schema) schemaMap.get(name.schema.name); schema.indexLookup.removeParent(name); schema.constraintLookup.removeParent(name); schema.triggerLookup.removeParent(name); } finally { writeLock.unlock(); } }
Removes any foreign key Constraint objects (exported keys) held by any tables referenced by the specified table.

This method is called as the last step of a successful call to dropTable() in order to ensure that the dropped Table ceases to be referenced when enforcing referential integrity.

Params:
  • toDrop – The table to which other tables may be holding keys. This is a table that is in the process of being dropped.
/** * Removes any foreign key Constraint objects (exported keys) held by any * tables referenced by the specified table. <p> * * This method is called as the last step of a successful call to * dropTable() in order to ensure that the dropped Table ceases to be * referenced when enforcing referential integrity. * * @param toDrop The table to which other tables may be holding keys. * This is a table that is in the process of being dropped. */
void removeExportedKeys(Table toDrop) { writeLock.lock(); try { // toDrop.schema may be null because it is not registered Schema schema = (Schema) schemaMap.get(toDrop.getSchemaName().name); for (int i = 0; i < schema.tableList.size(); i++) { Table table = (Table) schema.tableList.get(i); Constraint[] constraints = table.getConstraints(); for (int j = constraints.length - 1; j >= 0; j--) { Table refTable = constraints[j].getRef(); if (toDrop == refTable) { table.removeConstraint(j); } } } } finally { writeLock.unlock(); } } public Iterator databaseObjectIterator(String schemaName, int type) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName); return schema.schemaObjectIterator(type); } finally { readLock.unlock(); } } public Iterator databaseObjectIterator(int type) { readLock.lock(); try { Iterator it = schemaMap.values().iterator(); Iterator objects = new WrapperIterator(); while (it.hasNext()) { int targetType = type; if (type == SchemaObject.ROUTINE) { targetType = SchemaObject.FUNCTION; } Schema temp = (Schema) it.next(); SchemaObjectSet set = temp.getObjectSet(targetType); Object[] values; if (set.map.size() != 0) { values = new Object[set.map.size()]; set.map.valuesToArray(values); objects = new WrapperIterator(objects, new WrapperIterator(values)); } if (type == SchemaObject.ROUTINE) { set = temp.getObjectSet(SchemaObject.PROCEDURE); if (set.map.size() != 0) { values = new Object[set.map.size()]; set.map.valuesToArray(values); objects = new WrapperIterator(objects, new WrapperIterator(values)); } } } return objects; } finally { readLock.unlock(); } } // references private void addReferencesFrom(SchemaObject object) { OrderedHashSet set = object.getReferences(); HsqlName name = object.getName(); if (object instanceof Routine) { name = ((Routine) object).getSpecificName(); } if (set == null) { return; } for (int i = 0; i < set.size(); i++) { HsqlName referenced = (HsqlName) set.get(i); referenceMap.put(referenced, name); } } private void removeReferencesTo(OrderedHashSet set) { for (int i = 0; i < set.size(); i++) { HsqlName referenced = (HsqlName) set.get(i); referenceMap.remove(referenced); } } private void removeReferencesTo(HsqlName referenced) { referenceMap.remove(referenced); } private void removeReferencesFrom(SchemaObject object) { HsqlName name = object.getName(); OrderedHashSet set = object.getReferences(); if (object instanceof Routine) { name = ((Routine) object).getSpecificName(); } if (set == null) { return; } for (int i = 0; i < set.size(); i++) { HsqlName referenced = (HsqlName) set.get(i); referenceMap.remove(referenced, name); } } private void removeTableDependentReferences(Table table) { OrderedHashSet mainSet = table.getReferencesForDependents(); for (int i = 0; i < mainSet.size(); i++) { HsqlName name = (HsqlName) mainSet.get(i); SchemaObject object = null; switch (name.type) { case SchemaObject.CONSTRAINT : object = table.getConstraint(name.name); break; case SchemaObject.TRIGGER : object = table.getTrigger(name.name); break; case SchemaObject.COLUMN : object = table.getColumn(table.getColumnIndex(name.name)); break; default : continue; } removeReferencesFrom(object); } } public OrderedHashSet getReferencesTo(HsqlName object) { readLock.lock(); try { OrderedHashSet set = new OrderedHashSet(); Iterator it = referenceMap.get(object); while (it.hasNext()) { HsqlName name = (HsqlName) it.next(); set.add(name); } return set; } finally { readLock.unlock(); } } public OrderedHashSet getReferencesTo(HsqlName table, HsqlName column) { readLock.lock(); try { OrderedHashSet set = new OrderedHashSet(); Iterator it = referenceMap.get(table); while (it.hasNext()) { HsqlName name = (HsqlName) it.next(); SchemaObject object = getSchemaObject(name); OrderedHashSet references = object.getReferences(); if (references.contains(column)) { set.add(name); } } it = referenceMap.get(column); while (it.hasNext()) { HsqlName name = (HsqlName) it.next(); set.add(name); } return set; } finally { readLock.unlock(); } } private boolean isReferenced(HsqlName object) { writeLock.lock(); try { return referenceMap.containsKey(object); } finally { writeLock.unlock(); } } // public void getCascadingReferencesTo(HsqlName object, OrderedHashSet set) { readLock.lock(); try { OrderedHashSet newSet = new OrderedHashSet(); Iterator it = referenceMap.get(object); while (it.hasNext()) { HsqlName name = (HsqlName) it.next(); boolean added = set.add(name); if (added) { newSet.add(name); } } for (int i = 0; i < newSet.size(); i++) { HsqlName name = (HsqlName) newSet.get(i); getCascadingReferencesTo(name, set); } } finally { readLock.unlock(); } } public void getCascadingReferencesToSchema(HsqlName schema, OrderedHashSet set) { Iterator mainIterator = referenceMap.keySet().iterator(); while (mainIterator.hasNext()) { HsqlName name = (HsqlName) mainIterator.next(); if (name.schema != schema) { continue; } getCascadingReferencesTo(name, set); } for (int i = set.size() - 1; i >= 0; i--) { HsqlName name = (HsqlName) set.get(i); if (name.schema == schema) { set.remove(i); } } } public MultiValueHashMap getReferencesToSchema(String schemaName) { MultiValueHashMap map = new MultiValueHashMap(); Iterator mainIterator = referenceMap.keySet().iterator(); while (mainIterator.hasNext()) { HsqlName name = (HsqlName) mainIterator.next(); if (!name.schema.name.equals(schemaName)) { continue; } Iterator it = referenceMap.get(name); while (it.hasNext()) { map.put(name, it.next()); } } return map; } // public HsqlName getSchemaObjectName(HsqlName schemaName, String name, int type, boolean raise) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(schemaName.name); SchemaObjectSet set = null; if (schema == null) { if (raise) { throw Error.error(SchemaObjectSet.getGetErrorCode(type)); } else { return null; } } if (type == SchemaObject.ROUTINE) { set = schema.functionLookup; SchemaObject object = schema.functionLookup.getObject(name); if (object == null) { set = schema.procedureLookup; object = schema.procedureLookup.getObject(name); } } else { set = getSchemaObjectSet(schema, type); } if (raise) { set.checkExists(name); } return set.getName(name); } finally { readLock.unlock(); } } public SchemaObject getSchemaObject(HsqlName name) { readLock.lock(); try { Schema schema = (Schema) schemaMap.get(name.schema.name); if (schema == null) { return null; } switch (name.type) { case SchemaObject.SEQUENCE : return (SchemaObject) schema.sequenceList.get(name.name); case SchemaObject.TABLE : case SchemaObject.VIEW : return (SchemaObject) schema.tableList.get(name.name); case SchemaObject.CHARSET : return schema.charsetLookup.getObject(name.name); case SchemaObject.COLLATION : return schema.collationLookup.getObject(name.name); case SchemaObject.PROCEDURE : return schema.procedureLookup.getObject(name.name); case SchemaObject.FUNCTION : return schema.functionLookup.getObject(name.name); case RoutineSchema.SPECIFIC_ROUTINE : return schema.specificRoutineLookup.getObject(name.name); case RoutineSchema.ROUTINE : SchemaObject object = schema.functionLookup.getObject(name.name); if (object == null) { object = schema.procedureLookup.getObject(name.name); } return object; case SchemaObject.DOMAIN : case SchemaObject.TYPE : return schema.typeLookup.getObject(name.name); case SchemaObject.TRIGGER : { name = schema.triggerLookup.getName(name.name); if (name == null) { return null; } HsqlName tableName = name.parent; Table table = (Table) schema.tableList.get(tableName.name); return table.getTrigger(name.name); } case SchemaObject.CONSTRAINT : { name = schema.constraintLookup.getName(name.name); if (name == null) { return null; } HsqlName tableName = name.parent; Table table = (Table) schema.tableList.get(tableName.name); return table.getConstraint(name.name); } case SchemaObject.ASSERTION : return null; case SchemaObject.INDEX : name = schema.indexLookup.getName(name.name); if (name == null) { return null; } HsqlName tableName = name.parent; Table table = (Table) schema.tableList.get(tableName.name); return table.getUserIndex(name.name); case SchemaObject.REFERENCE : return schema.referenceLookup.getObject(name.name); } return null; } finally { readLock.unlock(); } } public void checkColumnIsReferenced(HsqlName tableName, HsqlName name) { OrderedHashSet set = getReferencesTo(tableName, name); if (!set.isEmpty()) { HsqlName objectName = (HsqlName) set.get(0); throw Error.error(ErrorCode.X_42502, objectName.getSchemaQualifiedStatementName()); } } public void checkObjectIsReferenced(HsqlName name) { OrderedHashSet set = getReferencesTo(name); HsqlName refName = null; for (int i = 0; i < set.size(); i++) { refName = (HsqlName) set.get(i); // except columns of same table if (refName.parent != name) { break; } refName = null; } if (refName == null) { return; } if (name.type == SchemaObject.CONSTRAINT) { return; } int errorCode = ErrorCode.X_42502; if (refName.type == SchemaObject.ConstraintTypes.FOREIGN_KEY) { errorCode = ErrorCode.X_42533; } throw Error.error(errorCode, refName.getSchemaQualifiedStatementName()); } public void checkSchemaNameCanChange(HsqlName name) { readLock.lock(); try { Iterator it = referenceMap.values().iterator(); HsqlName refName = null; mainLoop: while (it.hasNext()) { refName = (HsqlName) it.next(); switch (refName.type) { case SchemaObject.VIEW : case SchemaObject.ROUTINE : case SchemaObject.FUNCTION : case SchemaObject.PROCEDURE : case SchemaObject.TRIGGER : case SchemaObject.SPECIFIC_ROUTINE : if (refName.schema == name) { break mainLoop; } break; default : } refName = null; } if (refName == null) { return; } throw Error.error(ErrorCode.X_42502, refName.getSchemaQualifiedStatementName()); } finally { readLock.unlock(); } } public void addSchemaObject(SchemaObject object) { writeLock.lock(); try { HsqlName name = object.getName(); Schema schema = (Schema) schemaMap.get(name.schema.name); switch (name.type) { case SchemaObject.TABLE : { OrderedHashSet refs = ((Table) object).getReferencesForDependents(); for (int i = 0; i < refs.size(); i++) { HsqlName ref = (HsqlName) refs.get(i); switch (ref.type) { case SchemaObject.COLUMN : { int index = ((Table) object).findColumn(ref.name); ColumnSchema column = ((Table) object).getColumn(index); addSchemaObject(column); break; } } } break; } case SchemaObject.COLUMN : { OrderedHashSet refs = object.getReferences(); if (refs == null || refs.isEmpty()) { return; } addReferencesFrom(object); return; } } schema.addSchemaObject(database.nameManager, object, false); addReferencesFrom(object); } finally { writeLock.unlock(); } } public void removeSchemaObject(HsqlName name, boolean cascade) { writeLock.lock(); try { OrderedHashSet objectSet = new OrderedHashSet(); switch (name.type) { case SchemaObject.ROUTINE : case SchemaObject.PROCEDURE : case SchemaObject.FUNCTION : { RoutineSchema routine = (RoutineSchema) getSchemaObject(name); if (routine != null) { Routine[] specifics = routine.getSpecificRoutines(); for (int i = 0; i < specifics.length; i++) { getCascadingReferencesTo( specifics[i].getSpecificName(), objectSet); } } } break; case SchemaObject.SEQUENCE : case SchemaObject.TABLE : case SchemaObject.VIEW : case SchemaObject.TYPE : case SchemaObject.CHARSET : case SchemaObject.COLLATION : case SchemaObject.SPECIFIC_ROUTINE : getCascadingReferencesTo(name, objectSet); break; case SchemaObject.DOMAIN : OrderedHashSet set = getReferencesTo(name); Iterator it = set.iterator(); while (it.hasNext()) { HsqlName ref = (HsqlName) it.next(); if (ref.type == SchemaObject.COLUMN) { it.remove(); } } if (!set.isEmpty()) { HsqlName objectName = (HsqlName) set.get(0); throw Error.error( ErrorCode.X_42502, objectName.getSchemaQualifiedStatementName()); } break; } if (objectSet.isEmpty()) { removeSchemaObject(name); return; } if (!cascade) { HsqlName objectName = (HsqlName) objectSet.get(0); throw Error.error( ErrorCode.X_42502, objectName.getSchemaQualifiedStatementName()); } objectSet.add(name); removeSchemaObjects(objectSet); } finally { writeLock.unlock(); } } public void removeSchemaObjects(OrderedHashSet set) { writeLock.lock(); try { for (int i = 0; i < set.size(); i++) { HsqlName name = (HsqlName) set.get(i); if (name.parent != null) { removeSchemaObject(name); } } for (int i = 0; i < set.size(); i++) { HsqlName name = (HsqlName) set.get(i); if (name.parent == null) { removeSchemaObject(name); } } } finally { writeLock.unlock(); } } public void removeSchemaObject(HsqlName name) { writeLock.lock(); try { Schema schema = (Schema) schemaMap.get(name.schema.name); SchemaObject object = null; SchemaObjectSet set = null; switch (name.type) { case SchemaObject.SEQUENCE : set = schema.sequenceLookup; object = set.getObject(name.name); break; case SchemaObject.TABLE : case SchemaObject.VIEW : { set = schema.tableLookup; object = set.getObject(name.name); break; } case SchemaObject.COLUMN : { Table table = (Table) getSchemaObject(name.parent); if (table != null) { object = table.getColumn(table.getColumnIndex(name.name)); } break; } case SchemaObject.CHARSET : set = schema.charsetLookup; object = set.getObject(name.name); break; case SchemaObject.COLLATION : set = schema.collationLookup; object = set.getObject(name.name); break; case SchemaObject.PROCEDURE : { set = schema.procedureLookup; RoutineSchema routine = (RoutineSchema) set.getObject(name.name); object = routine; Routine[] specifics = routine.getSpecificRoutines(); for (int i = 0; i < specifics.length; i++) { removeSchemaObject(specifics[i].getSpecificName()); } break; } case SchemaObject.FUNCTION : { set = schema.functionLookup; RoutineSchema routine = (RoutineSchema) set.getObject(name.name); object = routine; Routine[] specifics = routine.getSpecificRoutines(); for (int i = 0; i < specifics.length; i++) { removeSchemaObject(specifics[i].getSpecificName()); } break; } case SchemaObject.SPECIFIC_ROUTINE : { set = schema.specificRoutineLookup; Routine routine = (Routine) set.getObject(name.name); object = routine; routine.routineSchema.removeSpecificRoutine(routine); if (routine.routineSchema.getSpecificRoutines().length == 0) { removeSchemaObject(routine.getName()); } break; } case SchemaObject.DOMAIN : case SchemaObject.TYPE : set = schema.typeLookup; object = set.getObject(name.name); break; case SchemaObject.INDEX : set = schema.indexLookup; break; case SchemaObject.CONSTRAINT : { set = schema.constraintLookup; if (name.parent.type == SchemaObject.TABLE) { Table table = (Table) schema.tableList.get(name.parent.name); object = table.getConstraint(name.name); table.removeConstraint(name.name); } else if (name.parent.type == SchemaObject.DOMAIN) { Type type = (Type) schema.typeLookup.getObject( name.parent.name); object = type.userTypeModifier.getConstraint(name.name); type.userTypeModifier.removeConstraint(name.name); } break; } case SchemaObject.TRIGGER : { set = schema.triggerLookup; Table table = (Table) schema.tableList.get(name.parent.name); object = table.getTrigger(name.name); if (object != null) { table.removeTrigger((TriggerDef) object); } break; } case SchemaObject.REFERENCE : { set = schema.referenceLookup; object = set.getObject(name.name); break; } default : throw Error.runtimeError(ErrorCode.U_S0500, "SchemaManager"); } if (object != null) { database.getGranteeManager().removeDbObject(name); removeReferencesFrom(object); } if (set != null) { set.remove(name.name); } removeReferencesTo(name); } finally { writeLock.unlock(); } } public void renameSchemaObject(HsqlName name, HsqlName newName) { writeLock.lock(); try { if (name.schema != newName.schema) { throw Error.error(ErrorCode.X_42505, newName.schema.name); } checkObjectIsReferenced(name); Schema schema = (Schema) schemaMap.get(name.schema.name); SchemaObjectSet set = getSchemaObjectSet(schema, name.type); set.rename(name, newName); } finally { writeLock.unlock(); } } public void replaceReferences(SchemaObject oldObject, SchemaObject newObject) { writeLock.lock(); try { removeReferencesFrom(oldObject); addReferencesFrom(newObject); } finally { writeLock.unlock(); } } public String[] getSQLArray() { readLock.lock(); try { OrderedHashSet resolved = new OrderedHashSet(); OrderedHashSet unresolved = new OrderedHashSet(); HsqlArrayList list = new HsqlArrayList(); Iterator schemas = schemaMap.values().iterator(); schemas = schemaMap.values().iterator(); // build up set of simple objects while (schemas.hasNext()) { Schema schema = (Schema) schemas.next(); if (SqlInvariants.isSystemSchemaName(schema.getName().name)) { continue; } if (SqlInvariants.isLobsSchemaName(schema.getName().name)) { continue; } list.add(schema.getSQL()); schema.addSimpleObjects(unresolved); } // list all simple objects in refernece order while (true) { Iterator it = unresolved.iterator(); if (!it.hasNext()) { break; } OrderedHashSet newResolved = new OrderedHashSet(); SchemaObjectSet.addAllSQL(resolved, unresolved, list, it, newResolved); unresolved.removeAll(newResolved); if (newResolved.size() == 0) { break; } } schemas = schemaMap.values().iterator(); // while (schemas.hasNext()) { Schema schema = (Schema) schemas.next(); if (SqlInvariants.isLobsSchemaName(schema.getName().name)) { continue; } if (SqlInvariants.isSystemSchemaName(schema.getName().name)) { continue; } list.addAll(schema.getSQLArray(resolved, unresolved)); } while (true) { Iterator it = unresolved.iterator(); if (!it.hasNext()) { break; } OrderedHashSet newResolved = new OrderedHashSet(); SchemaObjectSet.addAllSQL(resolved, unresolved, list, it, newResolved); unresolved.removeAll(newResolved); if (newResolved.size() == 0) { break; } } Iterator it = unresolved.iterator(); while (it.hasNext()) { SchemaObject object = (SchemaObject) it.next(); if (object instanceof Routine) { list.add(((Routine) object).getSQLDeclaration()); } } it = unresolved.iterator(); while (it.hasNext()) { SchemaObject object = (SchemaObject) it.next(); if (object instanceof Routine) { list.add(((Routine) object).getSQLAlter()); } else { list.add(object.getSQL()); } } it = unresolved.iterator(); while (it.hasNext()) { SchemaObject object = (SchemaObject) it.next(); if (object instanceof ReferenceObject) { list.add(object.getSQL()); } } schemas = schemaMap.values().iterator(); while (schemas.hasNext()) { Schema schema = (Schema) schemas.next(); if (SqlInvariants.isLobsSchemaName(schema.getName().name)) { continue; } if (SqlInvariants.isSystemSchemaName(schema.getName().name)) { continue; } HsqlArrayList t = schema.getTriggerSQL(); if (t.size() > 0) { list.add(Schema.getSetSchemaSQL(schema.getName())); list.addAll(t); } } schemas = schemaMap.values().iterator(); while (schemas.hasNext()) { Schema schema = (Schema) schemas.next(); list.addAll(schema.getSequenceRestartSQL()); } if (defaultSchemaHsqlName != null) { StringBuilder sb = new StringBuilder(); sb.append(Tokens.T_SET).append(' ').append(Tokens.T_DATABASE); sb.append(' ').append(Tokens.T_DEFAULT).append(' '); sb.append(Tokens.T_INITIAL).append(' ').append( Tokens.T_SCHEMA); sb.append(' ').append(defaultSchemaHsqlName.statementName); list.add(sb.toString()); } String[] array = new String[list.size()]; list.toArray(array); return array; } finally { readLock.unlock(); } } public String[] getTablePropsSQL(boolean withHeader) { readLock.lock(); try { HsqlArrayList tableList = getAllTables(false); HsqlArrayList list = new HsqlArrayList(); for (int i = 0; i < tableList.size(); i++) { Table t = (Table) tableList.get(i); if (t.isText()) { String[] ddl = t.getSQLForTextSource(withHeader); list.addAll(ddl); } String ddl = t.getSQLForReadOnly(); if (ddl != null) { list.add(ddl); } if (t.isCached()) { ddl = t.getSQLForClustered(); if (ddl != null) { list.add(ddl); } } } String[] array = new String[list.size()]; list.toArray(array); return array; } finally { readLock.unlock(); } } public String[] getTableSpaceSQL() { readLock.lock(); try { HsqlArrayList tableList = getAllTables(false); HsqlArrayList list = new HsqlArrayList(); for (int i = 0; i < tableList.size(); i++) { Table t = (Table) tableList.get(i); if (t.isCached()) { String ddl = t.getSQLForTableSpace(); if (ddl != null) { list.add(ddl); } } } String[] array = new String[list.size()]; list.toArray(array); return array; } finally { readLock.unlock(); } } public String[] getIndexRootsSQL() { readLock.lock(); try { Session sysSession = database.sessionManager.getSysSession(); long[][] rootsArray = getIndexRoots(sysSession); HsqlArrayList tableList = getAllTables(true); HsqlArrayList list = new HsqlArrayList(); for (int i = 0; i < rootsArray.length; i++) { Table table = (Table) tableList.get(i); if (rootsArray[i] != null && rootsArray[i].length > 0 && rootsArray[i][0] != -1) { String ddl = table.getIndexRootsSQL(rootsArray[i]); list.add(ddl); } } String[] array = new String[list.size()]; list.toArray(array); return array; } finally { readLock.unlock(); } } public String[] getCommentsSQL() { readLock.lock(); try { HsqlArrayList tableList = getAllTables(false); HsqlArrayList list = new HsqlArrayList(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < tableList.size(); i++) { Table table = (Table) tableList.get(i); if (table.getTableType() == Table.INFO_SCHEMA_TABLE) { continue; } int colCount = table.getColumnCount(); for (int j = 0; j < colCount; j++) { ColumnSchema column = table.getColumn(j); if (column.getName().comment == null) { continue; } sb.setLength(0); sb.append(Tokens.T_COMMENT).append(' ').append( Tokens.T_ON); sb.append(' ').append(Tokens.T_COLUMN).append(' '); sb.append( table.getName().getSchemaQualifiedStatementName()); sb.append('.').append(column.getName().statementName); sb.append(' ').append(Tokens.T_IS).append(' '); sb.append( StringConverter.toQuotedString( column.getName().comment, '\'', true)); list.add(sb.toString()); } if (table.getName().comment == null) { continue; } sb.setLength(0); sb.append(Tokens.T_COMMENT).append(' ').append(Tokens.T_ON); sb.append(' ').append(Tokens.T_TABLE).append(' '); sb.append(table.getName().getSchemaQualifiedStatementName()); sb.append(' ').append(Tokens.T_IS).append(' '); sb.append( StringConverter.toQuotedString( table.getName().comment, '\'', true)); list.add(sb.toString()); } Iterator it = databaseObjectIterator(SchemaObject.ROUTINE); while (it.hasNext()) { SchemaObject object = (SchemaObject) it.next(); if (object.getName().comment == null) { continue; } sb.setLength(0); sb.append(Tokens.T_COMMENT).append(' ').append(Tokens.T_ON); sb.append(' ').append(Tokens.T_ROUTINE).append(' '); sb.append(object.getName().getSchemaQualifiedStatementName()); sb.append(' ').append(Tokens.T_IS).append(' '); sb.append( StringConverter.toQuotedString( object.getName().comment, '\'', true)); list.add(sb.toString()); } String[] array = new String[list.size()]; list.toArray(array); return array; } finally { readLock.unlock(); } } long[][] tempIndexRoots; public void setTempIndexRoots(long[][] roots) { tempIndexRoots = roots; } public long[][] getIndexRoots(Session session) { readLock.lock(); try { if (tempIndexRoots != null) { long[][] roots = tempIndexRoots; tempIndexRoots = null; return roots; } HsqlArrayList allTables = getAllTables(true); HsqlArrayList list = new HsqlArrayList(); for (int i = 0, size = allTables.size(); i < size; i++) { Table t = (Table) allTables.get(i); if (t.getTableType() == TableBase.CACHED_TABLE) { long[] roots = t.getIndexRootsArray(); list.add(roots); } else { list.add(null); } } long[][] array = new long[list.size()][]; list.toArray(array); return array; } finally { readLock.unlock(); } }
called after the completion of defrag
/** * called after the completion of defrag */
public void setIndexRoots(long[][] roots) { readLock.lock(); try { HsqlArrayList allTables = database.schemaManager.getAllTables(true); for (int i = 0, size = allTables.size(); i < size; i++) { Table t = (Table) allTables.get(i); if (t.getTableType() == TableBase.CACHED_TABLE) { long[] rootsArray = roots[i]; if (rootsArray != null) { t.setIndexRoots(rootsArray); } } } } finally { readLock.unlock(); } } public void setDefaultTableType(int type) { defaultTableType = type; } public int getDefaultTableType() { return defaultTableType; } public void createSystemTables() { dualTable = TableUtil.newSingleColumnTable(database, SqlInvariants.DUAL_TABLE_HSQLNAME, TableBase.SYSTEM_TABLE, SqlInvariants.DUAL_COLUMN_HSQLNAME, Type.SQL_VARCHAR); dualTable.insertSys(database.sessionManager.getSysSession(), dualTable.getRowStore(null), new Object[]{ "X" }); dualTable.setDataReadOnly(true); Type[] columnTypes = new Type[] { Type.SQL_BIGINT, Type.SQL_BIGINT, Type.SQL_BIGINT, TypeInvariants.SQL_IDENTIFIER, TypeInvariants.SQL_IDENTIFIER, Type.SQL_BOOLEAN }; HsqlName tableName = database.nameManager.getSubqueryTableName(); HashMappedList columnList = new HashMappedList(); for (int i = 0; i < columnTypes.length; i++) { HsqlName name = HsqlNameManager.getAutoColumnName(i + 1); ColumnSchema column = new ColumnSchema(name, columnTypes[i], true, false, null); columnList.add(name.name, column); } dataChangeTable = new TableDerived(database, tableName, TableBase.CHANGE_SET_TABLE, columnTypes, columnList, new int[]{ 0 }); dataChangeTable.createIndexForColumns(null, new int[]{ 1 }); } }