/* This file is part of VoltDB.
* Copyright (C) 2008-2017 VoltDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.sysprocs;
import org.voltdb.DependencyPair;
import org.voltdb.DependencyPair.TableDependencyPair;
import org.voltdb.ParameterSet;
import org.voltdb.ProcInfo;
import org.voltdb.SystemProcedureExecutionContext;
import org.voltdb.VoltDB;
import org.voltdb.VoltTable;
import org.voltdb.common.Constants;
import org.voltdb.dtxn.DtxnConstants;
import org.voltdb.utils.VoltTableUtil;
import java.util.List;
import java.util.Map;
/**
* Execute a SwapTables as an multi-partition SQL statement.
* This code coordinates the execution of the plan fragments generated by the
* embedded planner process.
*
* AdHocBase implements the core logic.
* This subclass is needed for @ProcInfo.
*/
@ProcInfo(singlePartition = false)
public class SwapTables extends AdHocBase {
private static final int DEP_swapTables = (int) SysProcFragmentId.PF_swapTables | DtxnConstants.MULTIPARTITION_DEPENDENCY;
private static final int DEP_swapTablesAggregate = (int) SysProcFragmentId.PF_swapTablesAggregate;
@Override
public long[] getPlanFragmentIds() {
return new long[] { SysProcFragmentId.PF_swapTables, SysProcFragmentId.PF_swapTablesAggregate };
}
@Override
public DependencyPair executePlanFragment(Map<Integer, List<VoltTable>> dependencies, long fragmentId, ParameterSet params, SystemProcedureExecutionContext context) {
VoltTable dummy = new VoltTable(STATUS_SCHEMA);
dummy.addRow(STATUS_OK);
if (fragmentId == SysProcFragmentId.PF_swapTables) {
// issue the callback once on each node
if (context.isLowestSiteId()) {
VoltDB.instance().swapTables((String) params.getParam(0), (String) params.getParam(1));
}
return new TableDependencyPair(DEP_swapTables, dummy);
}
else if (fragmentId == SysProcFragmentId.PF_swapTablesAggregate) {
return new TableDependencyPair(DEP_swapTablesAggregate,
VoltTableUtil.unionTables(dependencies.get(DEP_swapTables)));
}
assert false;
return null;
}
/**
* System procedure run hook.
* Use the base class implementation.
*
* @param ctx execution context
* @param serializedBatchData serialized batch data
*
* @return results as VoltTable array
*/
public VoltTable[] run(SystemProcedureExecutionContext ctx, byte[] serializedBatchData) {
VoltTable[] result = runAdHoc(ctx, serializedBatchData);
String stmt = new String(
decodeSerializedBatchData(serializedBatchData).getSecond()[0].sql,
Constants.UTF8ENCODING);
// stmt is of the format "@SwapTables <table1> <table2>"
String[] stmtParams = stmt.split(" ");
performSwapTablesCallback(stmtParams[1], stmtParams[2]);
return result;
}
private VoltTable[] performSwapTablesCallback(String oneTable, String otherTable)
{
SynthesizedPlanFragment pfs[] = new SynthesizedPlanFragment[2];
pfs[0] = new SynthesizedPlanFragment();
pfs[0].fragmentId = SysProcFragmentId.PF_swapTables;
pfs[0].outputDepId = DEP_swapTables;
pfs[0].inputDepIds = new int[]{};
pfs[0].multipartition = true;
pfs[0].parameters = ParameterSet.fromArrayNoCopy(oneTable, otherTable);
pfs[1] = new SynthesizedPlanFragment();
pfs[1].fragmentId = SysProcFragmentId.PF_swapTablesAggregate;
pfs[1].outputDepId = DEP_swapTablesAggregate;
pfs[1].inputDepIds = new int[]{DEP_swapTables};
pfs[1].multipartition = false;
pfs[1].parameters = ParameterSet.emptyParameterSet();
return executeSysProcPlanFragments(pfs, DEP_swapTablesAggregate);
}
}