private boolean applies(SchemaContext sc, DMLStatement stmt) throws PEException {
   if (stmt instanceof UpdateStatement) {
     UpdateStatement us = (UpdateStatement) stmt;
     for (Iterator<ExpressionNode> iter = us.getUpdateExpressionsEdge().iterator();
         iter.hasNext(); ) {
       FunctionCall fc = (FunctionCall) iter.next();
       ColumnInstance lhs = (ColumnInstance) fc.getParametersEdge().get(0);
       if (lhs.getPEColumn().isPartOfContainerDistributionVector())
         throw new SchemaException(
             new ErrorInfo(
                 AvailableErrors.INVALID_CONTAINER_DISCRIMINANT_COLUMN_UPDATE,
                 lhs.getPEColumn().getName().getUnquotedName().get(),
                 lhs.getPEColumn().getTable().getName().getUnquotedName().get()));
     }
     return false;
   } else if (stmt instanceof DeleteStatement) {
     DeleteStatement ds = (DeleteStatement) stmt;
     PETable pet = ds.getTargetDeleteEdge().get().getAbstractTable().asTable();
     if (pet.isContainerBaseTable(sc)) {
       List<Part> parts = DiscriminantCollector.getDiscriminants(sc, ds.getWhereClause());
       if (parts == null || parts.isEmpty())
         throw new SchemaException(
             new ErrorInfo(
                 AvailableErrors.INVALID_CONTAINER_DELETE, pet.getName().getUnquotedName().get()));
       else {
         List<SchemaCacheKey<PEContainerTenant>> matchingTenants = convert(sc, parts);
         stmt.getBlock().store(ContainerBaseTableRewriteTransformFactory.class, matchingTenants);
         return true;
       }
     }
     return false;
   }
   return false;
 }
 private static SchemaCacheKey<PEContainerTenant> convert(
     SchemaContext sc, Map<PEColumn, ConstantExpression> unorderedValues) {
   PETable ofTab = unorderedValues.keySet().iterator().next().getTable().asTable();
   ContainerDistributionVector cdv = (ContainerDistributionVector) ofTab.getDistributionVector(sc);
   PEContainer cont = cdv.getContainer(sc);
   List<PEColumn> discColOrder = cont.getDiscriminantColumns(sc);
   List<Pair<PEColumn, LiteralExpression>> ordered =
       new ArrayList<Pair<PEColumn, LiteralExpression>>();
   for (PEColumn pec : discColOrder) {
     ConstantExpression ce = unorderedValues.get(pec);
     if (ce == null) throw new SchemaException(Pass.PLANNER, "Malformed discriminant key");
     ordered.add(new Pair<PEColumn, LiteralExpression>(pec, (LiteralExpression) ce));
   }
   String discValue = PEContainerTenant.buildDiscriminantValue(sc, sc.getValues(), ordered);
   return PEContainerTenant.getContainerTenantKey(cont, discValue);
 }
 private List<SchemaCacheKey<PEContainerTenant>> getPertinentTenants(
     PlannerContext pc, DMLStatement stmt) throws PEException {
   SchemaContext sc = pc.getContext();
   if (stmt instanceof UpdateStatement) {
     UpdateStatement us = (UpdateStatement) stmt;
     for (Iterator<ExpressionNode> iter = us.getUpdateExpressionsEdge().iterator();
         iter.hasNext(); ) {
       FunctionCall fc = (FunctionCall) iter.next();
       ColumnInstance lhs = (ColumnInstance) fc.getParametersEdge().get(0);
       if (lhs.getPEColumn().isPartOfContainerDistributionVector())
         throw new SchemaException(
             Pass.PLANNER,
             "Invalid update: discriminant column "
                 + lhs.getPEColumn().getName().getSQL()
                 + " of container base table "
                 + lhs.getPEColumn().getTable().getName().getSQL()
                 + " cannot be updated");
     }
   } else if (stmt instanceof DeleteStatement) {
     DeleteStatement ds = (DeleteStatement) stmt;
     PETable pet = ds.getTargetDeleteEdge().get().getAbstractTable().asTable();
     if (pet.isContainerBaseTable(sc)) {
       List<Part> parts = DiscriminantCollector.getDiscriminants(sc, ds.getWhereClause());
       if (parts == null || parts.isEmpty())
         throw new SchemaException(
             Pass.PLANNER,
             "Invalid delete on container base table "
                 + pet.getName().getSQL()
                 + ".  Not restricted by discriminant columns");
       else {
         List<SchemaCacheKey<PEContainerTenant>> matchingTenants = convert(sc, parts);
         return matchingTenants;
       }
     }
   }
   return null;
 }
 @Override
 public void plan(SchemaContext sc, ExecutionSequence es, BehaviorConfiguration config)
     throws PEException {
   MultiMap<PEDatabase, PETable> plain = new MultiMap<PEDatabase, PETable>();
   MultiMap<PEDatabase, PETable> fks = new MultiMap<PEDatabase, PETable>();
   MultiMap<PEDatabase, PEViewTable> views = new MultiMap<PEDatabase, PEViewTable>();
   AddStorageSiteStatement.sortTablesOnGroup(sc, onGroup, plain, fks, views);
   ListSet<PEDatabase> dbs = new ListSet<PEDatabase>();
   dbs.addAll(views.keySet());
   dbs.addAll(plain.keySet());
   dbs.addAll(fks.keySet());
   Pair<List<PEAbstractTable<?>>, Boolean> tableDeclOrder =
       AddStorageSiteStatement.buildTableDeclOrder(sc, plain, fks);
   MultiMap<RangeDistribution, PETable> tablesByRange = new MultiMap<RangeDistribution, PETable>();
   for (PEAbstractTable<?> abst : tableDeclOrder.getFirst()) {
     if (abst.isView()) continue;
     PETable pet = abst.asTable();
     if (pet.getDistributionVector(sc).isRange()) {
       RangeDistributionVector rdv = (RangeDistributionVector) pet.getDistributionVector(sc);
       tablesByRange.put(rdv.getRangeDistribution().getDistribution(sc), pet);
     }
   }
   List<AddStorageGenRangeInfo> rangeInfo = buildRangeInfo(sc, tablesByRange);
   /*
   for(AddStorageGenRangeInfo info : rangeInfo) {
   	info.display(System.out);
   }
   */
   es.append(
       new ComplexDDLExecutionStep(
           null,
           onGroup,
           null,
           Action.ALTER,
           new RebalanceCallback(onGroup, rangeInfo, tableDeclOrder.getSecond())));
 }