/** * 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>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 name of the table or view to drop * @param ifExists if true and if the Table to drop does not exist, fail silently, else throw * @param isView true if the name argument refers to a View * @param session the connected context in which to perform this operation * @throws HsqlException if any of the checks listed above fail */ void dropTable(Session session, String name, boolean ifExists, boolean isView) throws HsqlException { Table toDrop = null; int dropIndex = -1; for (int i = 0; i < tTable.size(); i++) { toDrop = (Table) tTable.get(i); if (toDrop.equals(session, name) && isView == toDrop.isView()) { dropIndex = i; break; } else { toDrop = null; } } if (dropIndex == -1) { if (ifExists) { return; } else { throw Trace.error(isView ? Trace.VIEW_NOT_FOUND : Trace.TABLE_NOT_FOUND, name); } } if (!toDrop.isTemp()) { session.checkDDLWrite(); } if (isView) { checkViewIsInView((View) toDrop); } else { checkTableIsReferenced(toDrop); checkTableIsInView(toDrop.tableName.name); } tTable.remove(dropIndex); removeExportedKeys(toDrop); userManager.removeDbObject(toDrop.getName()); triggerNameList.removeOwner(toDrop.tableName); indexNameList.removeOwner(toDrop.tableName); constraintNameList.removeOwner(toDrop.tableName); toDrop.dropTriggers(); toDrop.drop(); session.setScripting(!toDrop.isTemp()); session.commit(); }
/** Returns an array of views that reference a sequence. */ View[] getViewsWithSequence(NumberSequence sequence) { HsqlArrayList list = null; for (int i = 0; i < tTable.size(); i++) { Table t = (Table) tTable.get(i); if (t.isView()) { boolean found = ((View) t).hasSequence(sequence); if (found) { if (list == null) { list = new HsqlArrayList(); } list.add(t); } } } return list == null ? null : (View[]) list.toArray(new View[list.size()]); }
/** * Returns an array of views that reference the specified table or the specified column if column * parameter is not null. */ private View[] getViewsWithTable(String table, String column) { HsqlArrayList list = null; for (int i = 0; i < tTable.size(); i++) { Table t = (Table) tTable.get(i); if (t.isView()) { boolean found = column == null ? ((View) t).hasTable(table) : ((View) t).hasColumn(table, column); if (found) { if (list == null) { list = new HsqlArrayList(); } list.add(t); } } } return list == null ? null : (View[]) list.toArray(new View[list.size()]); }
void moveConditionsToInner(Session session, RangeVariable[] ranges) { Expression[] colExpr; int exclude; HsqlArrayList conditionsList; Expression condition = null; if (whereConditions.length > 1) { return; } if (joinConditions.length > 1) { return; } for (int i = 0; i < ranges.length; i++) { if (ranges[i].isLeftJoin || ranges[i].isRightJoin) { return; } } exclude = ArrayUtil.find(ranges, this); conditionsList = new HsqlArrayList(); addConditionsToList(conditionsList, joinConditions[0].indexCond); if (joinConditions[0].indexCond != null && joinConditions[0].indexCond[0] != joinConditions[0].indexEndCond[0]) { addConditionsToList(conditionsList, joinConditions[0].indexEndCond); } addConditionsToList(conditionsList, whereConditions[0].indexCond); addConditionsToList(conditionsList, whereConditions[0].indexEndCond); RangeVariableResolver.decomposeAndConditions( session, joinConditions[0].nonIndexCondition, conditionsList); RangeVariableResolver.decomposeAndConditions( session, whereConditions[0].nonIndexCondition, conditionsList); for (int i = conditionsList.size() - 1; i >= 0; i--) { Expression e = (Expression) conditionsList.get(i); if (e == null || e.isTrue() || e.hasReference(ranges, exclude)) { conditionsList.remove(i); continue; } } if (conditionsList.size() == 0) { if (rangeTable.isView()) { ((TableDerived) rangeTable).resetToView(); } return; } QueryExpression queryExpression = rangeTable.getQueryExpression(); colExpr = ((QuerySpecification) queryExpression).exprColumns; for (int i = 0; i < conditionsList.size(); i++) { Expression e = (Expression) conditionsList.get(i); OrderedHashSet set = e.collectRangeVariables(null); e = e.duplicate(); e = e.replaceColumnReferences(this, colExpr); if (e.collectAllSubqueries(null) != null) { return; } if (set != null) { for (int j = 0; j < set.size(); j++) { RangeVariable range = (RangeVariable) set.get(j); if (this != range && range.rangeType == RangeVariable.TABLE_RANGE) { queryExpression.setCorrelated(); } } } condition = ExpressionLogical.andExpressions(condition, e); } queryExpression.addExtraConditions(condition); }
/** * Method declaration * * @param db * @param file * @param full * @param session * @throws SQLException */ static void scriptToFile(Database db, String file, boolean full, Session session) throws SQLException { if ((new File(file)).exists()) { // there must be no such file; overwriting not allowed for security throw Trace.error(Trace.FILE_IO_ERROR, file); } try { long time = 0; if (Trace.TRACE) { time = System.currentTimeMillis(); } // only ddl commands; needs not so much memory Result r; if (full) { // no drop, no insert, and no positions for cached tables r = db.getScript(false, false, false, session); } else { // no drop, no insert, but positions for cached tables r = db.getScript(false, false, true, session); } Record n = r.rRoot; FileWriter w = new FileWriter(file); while (n != null) { writeLine(w, (String) n.data[0]); n = n.next; } // inserts are done separetely to save memory HsqlArrayList tables = db.getTables(); for (int i = 0; i < tables.size(); i++) { Table t = (Table) tables.get(i); // cached tables have the index roots set in the ddl script if ((full || !t.isCached()) && !t.isTemp() && !t.isView() && (!t.isText() || !t.isDataReadOnly())) { Index primary = t.getPrimaryIndex(); Node x = primary.first(); while (x != null) { writeLine(w, t.getInsertStatement(x.getData())); x = primary.next(x); } } // fredt@users 20020221 - patch 513005 by sqlbob@users (RMP) if (t.isDataReadOnly() && !t.isTemp() && !t.isText()) { HsqlStringBuffer a = new HsqlStringBuffer("SET TABLE "); a.append(t.getName().statementName); a.append(" READONLY TRUE"); writeLine(w, a.toString()); } } w.close(); if (Trace.TRACE) { Trace.trace(time - System.currentTimeMillis()); } } catch (IOException e) { throw Trace.error(Trace.FILE_IO_ERROR, file + " " + e); } }
/** * 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>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 name of the table or view to drop * @param ifExists if true and if the Table to drop does not exist, fail silently, else throw * @param isView true if the name argument refers to a View * @param session the connected context in which to perform this operation * @throws SQLException if any of the checks listed above fail */ void dropTable(String name, boolean ifExists, boolean isView, Session session) throws SQLException { Table toDrop = null; int dropIndex = -1; int refererIndex = -1; Enumeration constraints = null; Constraint currentConstraint = null; Table refTable = null; boolean isRef = false; boolean isSelfRef = false; for (int i = 0; i < tTable.size(); i++) { toDrop = (Table) tTable.get(i); if (toDrop.equals(name, session) && isView == toDrop.isView()) { dropIndex = i; break; } else { toDrop = null; } } if (dropIndex == -1) { if (ifExists) { return; } else { throw Trace.error(isView ? Trace.VIEW_NOT_FOUND : Trace.TABLE_NOT_FOUND, name); } } constraints = toDrop.getConstraints().elements(); while (constraints.hasMoreElements()) { currentConstraint = (Constraint) constraints.nextElement(); if (currentConstraint.getType() != Constraint.MAIN) { continue; } refTable = currentConstraint.getRef(); isRef = (refTable != null); isSelfRef = (isRef && toDrop.equals(refTable)); if (isRef && !isSelfRef) { // cover the case where the referencing table // may have already been dropped for (int k = 0; k < tTable.size(); k++) { if (refTable.equals(tTable.get(k))) { refererIndex = k; break; } } if (refererIndex != -1) { // tony_lai@users 20020820 - patch 595156 throw Trace.error( Trace.INTEGRITY_CONSTRAINT_VIOLATION, currentConstraint.getName().name + " table: " + refTable.getName().name); } } } tTable.remove(dropIndex); removeExportedKeys(toDrop); aAccess.removeDbObject(toDrop.getName()); triggerNameList.removeOwner(toDrop.tableName); indexNameList.removeOwner(toDrop.tableName); toDrop.drop(); session.setScripting(!toDrop.isTemp()); session.commit(); }