/* 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.plannodes;
import org.json_voltpatches.JSONException;
import org.json_voltpatches.JSONObject;
import org.json_voltpatches.JSONStringer;
import org.voltdb.catalog.Database;
import org.voltdb.types.PlanNodeType;
public class InsertPlanNode extends AbstractOperationPlanNode {
private static class Members {
static final String MULTI_PARTITION = "MULTI_PARTITION";
static final String FIELD_MAP = "FIELD_MAP";
static final String UPSERT = "UPSERT";
static final String SOURCE_IS_PARTITIONED = "SOURCE_IS_PARTITIONED";
}
protected boolean m_multiPartition = false;
private int[] m_fieldMap;
private boolean m_isUpsert = false;
private boolean m_sourceIsPartitioned = false;
public boolean isUpsert() {
return m_isUpsert;
}
public void setUpsert(boolean isUpsert) {
this.m_isUpsert = isUpsert;
}
public InsertPlanNode() {
super();
}
public boolean getMultiPartition() {
return m_multiPartition;
}
public void setMultiPartition(boolean multiPartition) {
m_multiPartition = multiPartition;
}
public int[] getFieldMap() {
return m_fieldMap;
}
public void setFieldMap(int[] fieldMap) {
m_fieldMap = fieldMap;
}
public void setSourceIsPartitioned(boolean value) {
m_sourceIsPartitioned = value;
}
public boolean getSourceIsPartitioned() {
return m_sourceIsPartitioned;
}
@Override
public PlanNodeType getPlanNodeType() {
return PlanNodeType.INSERT;
}
@Override
public void toJSONString(JSONStringer stringer) throws JSONException {
super.toJSONString(stringer);
stringer.keySymbolValuePair(Members.MULTI_PARTITION, m_multiPartition);
toJSONIntArrayString(stringer, Members.FIELD_MAP, m_fieldMap);
if (m_isUpsert) {
stringer.keySymbolValuePair(Members.UPSERT, true);
}
if (m_sourceIsPartitioned) {
stringer.keySymbolValuePair(Members.SOURCE_IS_PARTITIONED, true);
}
}
@Override
public void loadFromJSONObject( JSONObject jobj, Database db ) throws JSONException {
super.loadFromJSONObject(jobj, db);
m_multiPartition = jobj.getBoolean(Members.MULTI_PARTITION);
m_fieldMap = loadIntArrayMemberFromJSON(jobj, Members.FIELD_MAP);
m_isUpsert = jobj.has(Members.UPSERT);
m_sourceIsPartitioned = jobj.has(Members.SOURCE_IS_PARTITIONED);
}
@Override
protected String explainPlanForNode(String indent) {
String type = "INSERT";
if (m_isUpsert) {
type = "UPSERT";
}
return type + " into \"" + m_targetTableName + "\"";
}
/** Order determinism for insert nodes depends on the determinism of child nodes. For subqueries producing
* unordered rows, the insert will be considered order-nondeterministic.
* */
@Override
public boolean isOrderDeterministic() {
assert(m_children != null);
assert(m_children.size() == 1);
// This implementation is very close to AbstractPlanNode's implementation of this
// method, except that we assert just one child.
// Java doesn't allow calls to super-super-class methods via super.super.
AbstractPlanNode child = m_children.get(0);
if (! child.isOrderDeterministic()) {
m_nondeterminismDetail = child.m_nondeterminismDetail;
return false;
}
return true;
}
}