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()))); }