/* * Licensed to CRATE Technology GmbH ("Crate") under one or more contributor * license agreements. See the NOTICE file distributed with this work for * additional information regarding copyright ownership. Crate licenses * this file to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may * obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations * under the License. * * However, if you have executed another commercial license agreement * with Crate these terms will supersede the license and you may use the * software solely pursuant to the terms of the relevant commercial agreement. */ package io.crate.analyze; import io.crate.analyze.symbol.Symbol; import io.crate.metadata.PartitionName; import io.crate.metadata.Reference; import io.crate.metadata.doc.DocTableInfo; import org.apache.lucene.util.BytesRef; import org.elasticsearch.common.lucene.BytesRefs; import javax.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class InsertFromValuesAnalyzedStatement extends AbstractInsertAnalyzedStatement { private final List<Symbol[]> onDuplicateKeyAssignments = new ArrayList<>(); private final List<String[]> onDuplicateKeyAssignmentsColumns = new ArrayList<>(); private final List<Object[]> sourceMaps = new ArrayList<>(); private final List<Map<String, String>> partitionMaps = new ArrayList<>(); private final List<String> ids = new ArrayList<>(); private final List<String> routingValues = new ArrayList<>(); private final List<Integer> bulkIndices = new ArrayList<>(); private final int numBulkResponses; private int numAddedGeneratedColumns = 0; public InsertFromValuesAnalyzedStatement(DocTableInfo tableInfo, int numBulkResponses) { this.numBulkResponses = numBulkResponses; super.tableInfo(tableInfo); if (tableInfo.isPartitioned()) { for (Map<String, String> partitionMap : partitionMaps) { partitionMap = new HashMap<>(tableInfo.partitionedByColumns().size()); for (Reference partInfo : tableInfo.partitionedByColumns()) { // initialize with null values for missing partitioned columns partitionMap.put(partInfo.ident().columnIdent().name(), null); } } } } public List<Map<String, String>> partitionMaps() { return partitionMaps; } // create and add a new partition map public Map<String, String> newPartitionMap() { Map<String, String> map = new HashMap<>(tableInfo().partitionedByColumns().size()); for (Reference partInfo : tableInfo().partitionedByColumns()) { // initialize with null values for missing partitioned columns map.put(partInfo.ident().columnIdent().fqn(), null); } partitionMaps.add(map); return map; } public @Nullable Map<String, String> currentPartitionMap() { return partitionMaps.get(partitionMaps.size() - 1); } private List<String> partitionedByColumnNames() { assert tableInfo != null : "tableInfo must not be null"; List<String> names = new ArrayList<>(tableInfo.partitionedByColumns().size()); for (Reference info : tableInfo.partitionedByColumns()) { names.add(info.ident().columnIdent().fqn()); } return names; } public List<String> generatePartitions() { List<String> partitionValues = new ArrayList<>(partitionMaps.size()); for (Map<String, String> map : partitionMaps) { List<BytesRef> values = new ArrayList<>(map.size()); List<String> columnNames = partitionedByColumnNames(); for (String columnName : columnNames) { values.add(BytesRefs.toBytesRef(map.get(columnName))); } PartitionName partitionName = new PartitionName(tableInfo().ident(), values); partitionValues.add(partitionName.asIndexName()); } return partitionValues; } public List<Object[]> sourceMaps() { return sourceMaps; } protected void addIdAndRouting(String id, @Nullable String clusteredByValue) { ids.add(id); if (clusteredByValue == null) { routingValues.add(id); } else { routingValues.add(clusteredByValue); } } public void addOnDuplicateKeyAssignments(Symbol[] assignments) { assert assignments != null && assignments.length != 0 : "must have updateAssignments!"; onDuplicateKeyAssignments.add(assignments); } public List<Symbol[]> onDuplicateKeyAssignments() { return onDuplicateKeyAssignments; } public void addOnDuplicateKeyAssignmentsColumns(String[] assignmentsColumns) { assert assignmentsColumns != null && assignmentsColumns.length != 0 : "must have updateAssignments columns!"; onDuplicateKeyAssignmentsColumns.add(assignmentsColumns); } public List<String[]> onDuplicateKeyAssignmentsColumns() { return onDuplicateKeyAssignmentsColumns; } public List<String> ids() { return ids; } public List<String> routingValues() { return routingValues; } @Override public <C, R> R accept(AnalyzedStatementVisitor<C, R> analyzedStatementVisitor, C context) { return analyzedStatementVisitor.visitInsertFromValuesStatement(this, context); } public int numBulkResponses() { return numBulkResponses; } public void addGeneratedColumn(Reference reference) { columns().add(reference); numAddedGeneratedColumns++; } public int numAddedGeneratedColumns() { return numAddedGeneratedColumns; } public List<Integer> bulkIndices() { return bulkIndices; } }