Scanner scanner = aggPlan.getScanner();
ResultIterator iterator = scanner.iterator();
try {
Tuple row = iterator.next();
final long mutationCount = (Long)aggProjector.getColumnProjector(0).getValue(row, PDataType.LONG, ptr);
return new MutationState(maxSize, connection) {
@Override
public long getUpdateCount() {
return mutationCount;
}
};
} finally {
iterator.close();
}
} finally {
if (cache != null) {
cache.close();
}
}
}
@Override
public ExplainPlan getExplainPlan() throws SQLException {
List<String> queryPlanSteps = aggPlan.getExplainPlan().getPlanSteps();
List<String> planSteps = Lists.newArrayListWithExpectedSize(queryPlanSteps.size()+1);
planSteps.add("UPSERT ROWS");
planSteps.addAll(queryPlanSteps);
return new ExplainPlan(planSteps);
}
};
}
}
////////////////////////////////////////////////////////////////////
// UPSERT SELECT run client-side
/////////////////////////////////////////////////////////////////////
return new MutationPlan() {
@Override
public PhoenixConnection getConnection() {
return connection;
}
@Override
public ParameterMetaData getParameterMetaData() {
return queryPlan.getContext().getBindManager().getParameterMetaData();
}
@Override
public MutationState execute() throws SQLException {
Scanner scanner = queryPlan.getScanner();
ResultIterator iterator = scanner.iterator();
if (upsertParallelIteratorFactory == null) {
return upsertSelect(statement, tableRef, projector, iterator, columnIndexes, pkSlotIndexes);
}
upsertParallelIteratorFactory.setRowProjector(projector);
upsertParallelIteratorFactory.setColumnIndexes(columnIndexes);
upsertParallelIteratorFactory.setPkSlotIndexes(pkSlotIndexes);
Tuple tuple;
long totalRowCount = 0;
while ((tuple=iterator.next()) != null) {// Runs query
KeyValue kv = tuple.getValue(0);
totalRowCount += PDataType.LONG.getCodec().decodeLong(kv.getBuffer(), kv.getValueOffset(), null);
}
// Return total number of rows that have been updated. In the case of auto commit being off
// the mutations will all be in the mutation state of the current connection.
return new MutationState(maxSize, statement.getConnection(), totalRowCount);
}
@Override
public ExplainPlan getExplainPlan() throws SQLException {
List<String> queryPlanSteps = queryPlan.getExplainPlan().getPlanSteps();
List<String> planSteps = Lists.newArrayListWithExpectedSize(queryPlanSteps.size()+1);
planSteps.add("UPSERT SELECT");
planSteps.addAll(queryPlanSteps);
return new ExplainPlan(planSteps);
}
};
}
////////////////////////////////////////////////////////////////////
// UPSERT VALUES
/////////////////////////////////////////////////////////////////////
if (nValuesToSet > numColsInTable) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.UPSERT_COLUMN_NUMBERS_MISMATCH)
.setMessage("Numbers of columns in table: " + numColsInTable + ". Number of values: " + nValuesToSet)
.build().buildException();
}
int nodeIndex = 0;
// Allocate array based on size of all columns in table,
// since some values may not be set (if they're nullable).
final StatementContext context = new StatementContext(upsert, connection, resolver, statement.getParameters(), new Scan());
UpsertValuesCompiler expressionBuilder = new UpsertValuesCompiler(context);
final byte[][] values = new byte[nValuesToSet][];
for (ParseNode valueNode : valueNodes) {
if (!valueNode.isConstant()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.VALUE_IN_UPSERT_NOT_CONSTANT).build().buildException();
}
PColumn column = allColumns.get(columnIndexes[nodeIndex]);
expressionBuilder.setColumn(column);
LiteralExpression literalExpression = (LiteralExpression)valueNode.accept(expressionBuilder);
byte[] byteValue = literalExpression.getBytes();
if (literalExpression.getDataType() != null) {
// If ColumnModifier from expression in SELECT doesn't match the
// column being projected into then invert the bits.
if (literalExpression.getColumnModifier() != column.getColumnModifier()) {
byte[] tempByteValue = Arrays.copyOf(byteValue, byteValue.length);
byteValue = ColumnModifier.SORT_DESC.apply(byteValue, 0, tempByteValue, 0, byteValue.length);
}
if (!literalExpression.getDataType().isCoercibleTo(column.getDataType(), literalExpression.getValue())) {
throw new TypeMismatchException(
literalExpression.getDataType(), column.getDataType(), "expression: "
+ literalExpression.toString() + " in column " + column);
}
if (!column.getDataType().isSizeCompatible(literalExpression.getDataType(),
literalExpression.getValue(), byteValue, literalExpression.getMaxLength(),
column.getMaxLength(), literalExpression.getScale(), column.getScale())) {
throw new SQLExceptionInfo.Builder(
SQLExceptionCode.DATA_INCOMPATIBLE_WITH_TYPE).setColumnName(column.getName().getString())
.setMessage("value=" + literalExpression.toString()).build().buildException();
}
}
byteValue = column.getDataType().coerceBytes(byteValue, literalExpression.getValue(),
literalExpression.getDataType(), literalExpression.getMaxLength(), literalExpression.getScale(),
column.getMaxLength(), column.getScale());
values[nodeIndex] = byteValue;
nodeIndex++;
}
return new MutationPlan() {
@Override
public PhoenixConnection getConnection() {
return connection;
}
@Override
public ParameterMetaData getParameterMetaData() {
return context.getBindManager().getParameterMetaData();
}
@Override
public MutationState execute() {
Map<ImmutableBytesPtr, Map<PColumn, byte[]>> mutation = Maps.newHashMapWithExpectedSize(1);
setValues(values, pkSlotIndexes, columnIndexes, tableRef.getTable(), mutation);
return new MutationState(tableRef, mutation, 0, maxSize, connection);
}
@Override
public ExplainPlan getExplainPlan() throws SQLException {
return new ExplainPlan(Collections.singletonList("PUT SINGLE ROW"));