Search in sources :

Example 11 with GeneratedReference

use of io.crate.metadata.GeneratedReference in project crate by crate.

the class CopyStatementPlanner method planCopyFrom.

public Plan planCopyFrom(CopyFromAnalyzedStatement analysis, Planner.Context context) {
    /**
         * copy from has two "modes":
         *
         * 1: non-partitioned tables or partitioned tables with partition ident --> import into single es index
         *    -> collect raw source and import as is
         *
         * 2: partitioned table without partition ident
         *    -> collect document and partition by values
         *    -> exclude partitioned by columns from document
         *    -> insert into es index (partition determined by partition by value)
         */
    DocTableInfo table = analysis.table();
    int clusteredByPrimaryKeyIdx = table.primaryKey().indexOf(analysis.table().clusteredBy());
    List<String> partitionedByNames;
    String partitionIdent = null;
    List<BytesRef> partitionValues;
    if (analysis.partitionIdent() == null) {
        if (table.isPartitioned()) {
            partitionedByNames = Lists.newArrayList(Lists.transform(table.partitionedBy(), ColumnIdent::fqn));
        } else {
            partitionedByNames = Collections.emptyList();
        }
        partitionValues = ImmutableList.of();
    } else {
        assert table.isPartitioned() : "table must be partitioned if partitionIdent is set";
        // partitionIdent is present -> possible to index raw source into concrete es index
        partitionValues = PartitionName.decodeIdent(analysis.partitionIdent());
        partitionIdent = analysis.partitionIdent();
        partitionedByNames = Collections.emptyList();
    }
    SourceIndexWriterProjection sourceIndexWriterProjection = new SourceIndexWriterProjection(table.ident(), partitionIdent, table.getReference(DocSysColumns.RAW), table.primaryKey(), table.partitionedBy(), partitionValues, table.clusteredBy(), clusteredByPrimaryKeyIdx, analysis.settings(), null, partitionedByNames.size() > 0 ? partitionedByNames.toArray(new String[partitionedByNames.size()]) : null, // autoCreateIndices
    table.isPartitioned());
    List<Projection> projections = Collections.<Projection>singletonList(sourceIndexWriterProjection);
    partitionedByNames.removeAll(Lists.transform(table.primaryKey(), ColumnIdent::fqn));
    int referencesSize = table.primaryKey().size() + partitionedByNames.size() + 1;
    referencesSize = clusteredByPrimaryKeyIdx == -1 ? referencesSize + 1 : referencesSize;
    List<Symbol> toCollect = new ArrayList<>(referencesSize);
    // add primaryKey columns
    for (ColumnIdent primaryKey : table.primaryKey()) {
        toCollect.add(table.getReference(primaryKey));
    }
    // add partitioned columns (if not part of primaryKey)
    Set<Reference> referencedReferences = new HashSet<>();
    for (String partitionedColumn : partitionedByNames) {
        Reference reference = table.getReference(ColumnIdent.fromPath(partitionedColumn));
        Symbol symbol;
        if (reference instanceof GeneratedReference) {
            symbol = ((GeneratedReference) reference).generatedExpression();
            referencedReferences.addAll(((GeneratedReference) reference).referencedReferences());
        } else {
            symbol = reference;
        }
        toCollect.add(symbol);
    }
    // add clusteredBy column (if not part of primaryKey)
    if (clusteredByPrimaryKeyIdx == -1 && table.clusteredBy() != null && !DocSysColumns.ID.equals(table.clusteredBy())) {
        toCollect.add(table.getReference(table.clusteredBy()));
    }
    // add _raw or _doc
    if (table.isPartitioned() && analysis.partitionIdent() == null) {
        toCollect.add(table.getReference(DocSysColumns.DOC));
    } else {
        toCollect.add(table.getReference(DocSysColumns.RAW));
    }
    // add columns referenced by generated columns which are used as partitioned by column
    for (Reference reference : referencedReferences) {
        if (!toCollect.contains(reference)) {
            toCollect.add(reference);
        }
    }
    DiscoveryNodes allNodes = clusterService.state().nodes();
    FileUriCollectPhase collectPhase = new FileUriCollectPhase(context.jobId(), context.nextExecutionPhaseId(), "copyFrom", getExecutionNodes(allNodes, analysis.settings().getAsInt("num_readers", allNodes.getSize()), analysis.nodePredicate()), analysis.uri(), toCollect, projections, analysis.settings().get("compression", null), analysis.settings().getAsBoolean("shared", null));
    Collect collect = new Collect(collectPhase, TopN.NO_LIMIT, 0, 1, 1, null);
    return Merge.ensureOnHandler(collect, context, Collections.singletonList(MergeCountProjection.INSTANCE));
}
Also used : DocTableInfo(io.crate.metadata.doc.DocTableInfo) GeneratedReference(io.crate.metadata.GeneratedReference) Collect(io.crate.planner.node.dql.Collect) Symbol(io.crate.analyze.symbol.Symbol) GeneratedReference(io.crate.metadata.GeneratedReference) Reference(io.crate.metadata.Reference) SourceIndexWriterProjection(io.crate.planner.projection.SourceIndexWriterProjection) WriterProjection(io.crate.planner.projection.WriterProjection) MergeCountProjection(io.crate.planner.projection.MergeCountProjection) SourceIndexWriterProjection(io.crate.planner.projection.SourceIndexWriterProjection) Projection(io.crate.planner.projection.Projection) FileUriCollectPhase(io.crate.planner.node.dql.FileUriCollectPhase) ColumnIdent(io.crate.metadata.ColumnIdent) BytesRef(org.apache.lucene.util.BytesRef) DiscoveryNodes(org.elasticsearch.cluster.node.DiscoveryNodes)

Example 12 with GeneratedReference

use of io.crate.metadata.GeneratedReference in project crate by crate.

the class TransportShardUpsertAction method getNotUsedNonGeneratedColumns.

public static Collection<ColumnIdent> getNotUsedNonGeneratedColumns(Reference[] targetColumns, DocTableInfo tableInfo) {
    Set<String> targetColumnsSet = new HashSet<>();
    Collection<ColumnIdent> columnsNotUsed = new ArrayList<>();
    if (targetColumns != null) {
        for (Reference targetColumn : targetColumns) {
            targetColumnsSet.add(targetColumn.column().fqn());
        }
    }
    for (Reference reference : tableInfo.columns()) {
        if (!reference.isNullable() && !(reference instanceof GeneratedReference || reference.defaultExpression() != null)) {
            if (!targetColumnsSet.contains(reference.column().fqn())) {
                columnsNotUsed.add(reference.column());
            }
        }
    }
    return columnsNotUsed;
}
Also used : ColumnIdent(io.crate.metadata.ColumnIdent) GeneratedReference(io.crate.metadata.GeneratedReference) GeneratedReference(io.crate.metadata.GeneratedReference) BytesReference(org.elasticsearch.common.bytes.BytesReference) Reference(io.crate.metadata.Reference) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet)

Example 13 with GeneratedReference

use of io.crate.metadata.GeneratedReference in project crate by crate.

the class UserDefinedFunctionService method validateFunctionIsNotInUseByGeneratedColumn.

void validateFunctionIsNotInUseByGeneratedColumn(String schema, String functionName, UserDefinedFunctionsMetadata functionsMetadata, ClusterState currentState) {
    // The iteration of schemas/tables must happen on the node context WITHOUT the UDF already removed.
    // Otherwise the lazy table factories will already fail while evaluating generated functionsMetadata.
    // To avoid that, a copy of the node context with the removed UDF function is used on concrete expression evaluation.
    var nodeCtxWithRemovedFunction = new NodeContext(nodeCtx.functions().copyOf());
    updateImplementations(schema, functionsMetadata.functionsMetadata().stream(), nodeCtxWithRemovedFunction);
    var metadata = currentState.metadata();
    var indices = Stream.of(metadata.getConcreteAllIndices()).filter(NO_BLOB_NOR_DANGLING).map(IndexParts::new).filter(indexParts -> !indexParts.isPartitioned()).collect(Collectors.toList());
    var templates = metadata.getTemplates().keysIt();
    while (templates.hasNext()) {
        var indexParts = new IndexParts(templates.next());
        if (indexParts.isPartitioned()) {
            indices.add(indexParts);
        }
    }
    var indexNameExpressionResolver = new IndexNameExpressionResolver();
    for (var indexParts : indices) {
        var tableInfo = new DocTableInfoBuilder(nodeCtx, indexParts.toRelationName(), currentState, indexNameExpressionResolver).build();
        TableReferenceResolver tableReferenceResolver = new TableReferenceResolver(tableInfo.columns(), tableInfo.ident());
        CoordinatorTxnCtx coordinatorTxnCtx = CoordinatorTxnCtx.systemTransactionContext();
        ExpressionAnalyzer exprAnalyzer = new ExpressionAnalyzer(coordinatorTxnCtx, nodeCtxWithRemovedFunction, ParamTypeHints.EMPTY, tableReferenceResolver, null);
        for (var ref : tableInfo.columns()) {
            if (ref instanceof GeneratedReference) {
                var genRef = (GeneratedReference) ref;
                Expression expression = SqlParser.createExpression(genRef.formattedGeneratedExpression());
                try {
                    exprAnalyzer.convert(expression, new ExpressionAnalysisContext(coordinatorTxnCtx.sessionContext()));
                } catch (UnsupportedOperationException e) {
                    throw new IllegalArgumentException("Cannot drop function '" + functionName + "', it is still in use by '" + tableInfo + "." + genRef + "'");
                }
            }
        }
    }
}
Also used : ParamTypeHints(io.crate.analyze.ParamTypeHints) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) IndexParts(io.crate.metadata.IndexParts) UserDefinedFunctionAlreadyExistsException(io.crate.exceptions.UserDefinedFunctionAlreadyExistsException) FunctionName(io.crate.metadata.FunctionName) ClusterService(org.elasticsearch.cluster.service.ClusterService) FunctionProvider(io.crate.metadata.FunctionProvider) HashMap(java.util.HashMap) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver) Inject(org.elasticsearch.common.inject.Inject) ArrayList(java.util.ArrayList) ClusterState(org.elasticsearch.cluster.ClusterState) Metadata(org.elasticsearch.cluster.metadata.Metadata) ClusterStateUpdateTask(org.elasticsearch.cluster.ClusterStateUpdateTask) Locale(java.util.Locale) Map(java.util.Map) SqlParser(io.crate.sql.parser.SqlParser) Nullable(javax.annotation.Nullable) ScriptException(javax.script.ScriptException) NO_BLOB_NOR_DANGLING(io.crate.metadata.doc.DocSchemaInfo.NO_BLOB_NOR_DANGLING) NodeContext(io.crate.metadata.NodeContext) Iterator(java.util.Iterator) GeneratedReference(io.crate.metadata.GeneratedReference) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) DataType(io.crate.types.DataType) Signature(io.crate.metadata.functions.Signature) AcknowledgedResponse(org.elasticsearch.action.support.master.AcknowledgedResponse) Collectors(java.util.stream.Collectors) Lists2(io.crate.common.collections.Lists2) List(java.util.List) Logger(org.apache.logging.log4j.Logger) Stream(java.util.stream.Stream) UserDefinedFunctionUnknownException(io.crate.exceptions.UserDefinedFunctionUnknownException) FunctionType(io.crate.metadata.FunctionType) Singleton(org.elasticsearch.common.inject.Singleton) TimeValue(io.crate.common.unit.TimeValue) VisibleForTesting(io.crate.common.annotations.VisibleForTesting) Scalar(io.crate.metadata.Scalar) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) LogManager(org.apache.logging.log4j.LogManager) Expression(io.crate.sql.tree.Expression) ActionListener(org.elasticsearch.action.ActionListener) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) DocTableInfoBuilder(io.crate.metadata.doc.DocTableInfoBuilder) CoordinatorTxnCtx(io.crate.metadata.CoordinatorTxnCtx) ExpressionAnalysisContext(io.crate.analyze.expressions.ExpressionAnalysisContext) GeneratedReference(io.crate.metadata.GeneratedReference) NodeContext(io.crate.metadata.NodeContext) ExpressionAnalyzer(io.crate.analyze.expressions.ExpressionAnalyzer) IndexParts(io.crate.metadata.IndexParts) Expression(io.crate.sql.tree.Expression) DocTableInfoBuilder(io.crate.metadata.doc.DocTableInfoBuilder) IndexNameExpressionResolver(org.elasticsearch.cluster.metadata.IndexNameExpressionResolver) TableReferenceResolver(io.crate.analyze.expressions.TableReferenceResolver)

Example 14 with GeneratedReference

use of io.crate.metadata.GeneratedReference in project crate by crate.

the class InsertAnalyzer method ensureClusteredByPresentOrNotRequired.

private static void ensureClusteredByPresentOrNotRequired(List<Reference> targetColumnRefs, DocTableInfo tableInfo) {
    ColumnIdent clusteredBy = tableInfo.clusteredBy();
    if (clusteredBy == null || clusteredBy.equals(DocSysColumns.ID)) {
        return;
    }
    Reference clusteredByRef = tableInfo.getReference(clusteredBy);
    if (clusteredByRef.defaultExpression() != null) {
        return;
    }
    // target columns are always top level columns;
    // so we can compare against clusteredBy-root column in case clustered by is nested
    // In insert-from-query cases we cannot peek into object values to ensure the value is present
    // and need to rely on later runtime failures
    ColumnIdent clusteredByRoot = clusteredBy.getRoot();
    List<ColumnIdent> targetColumns = Lists2.mapLazy(targetColumnRefs, Reference::column);
    if (targetColumns.contains(clusteredByRoot)) {
        return;
    }
    if (clusteredByRef instanceof GeneratedReference) {
        GeneratedReference generatedClusteredBy = (GeneratedReference) clusteredByRef;
        var topLevelDependencies = Lists2.mapLazy(generatedClusteredBy.referencedReferences(), x -> x.column().getRoot());
        if (targetColumns.containsAll(topLevelDependencies)) {
            return;
        }
    }
    throw new IllegalArgumentException("Column `" + clusteredBy + "` is required but is missing from the insert statement");
}
Also used : ColumnIdent(io.crate.metadata.ColumnIdent) GeneratedReference(io.crate.metadata.GeneratedReference) QualifiedNameReference(io.crate.sql.tree.QualifiedNameReference) DynamicReference(io.crate.expression.symbol.DynamicReference) GeneratedReference(io.crate.metadata.GeneratedReference) Reference(io.crate.metadata.Reference)

Example 15 with GeneratedReference

use of io.crate.metadata.GeneratedReference in project crate by crate.

the class DocIndexMetadataTest method testArrayAsGeneratedColumn.

@Test
public void testArrayAsGeneratedColumn() throws Exception {
    DocIndexMetadata md = getDocIndexMetadataFromStatement("create table t1 (x as ([10, 20]))");
    GeneratedReference generatedReference = md.generatedColumnReferences().get(0);
    assertThat(generatedReference.valueType(), is(new ArrayType<>(DataTypes.INTEGER)));
}
Also used : ArrayType(io.crate.types.ArrayType) GeneratedReference(io.crate.metadata.GeneratedReference) CrateDummyClusterServiceUnitTest(io.crate.test.integration.CrateDummyClusterServiceUnitTest) Test(org.junit.Test)

Aggregations

GeneratedReference (io.crate.metadata.GeneratedReference)16 Reference (io.crate.metadata.Reference)14 ColumnIdent (io.crate.metadata.ColumnIdent)9 IndexReference (io.crate.metadata.IndexReference)4 ArrayList (java.util.ArrayList)4 VisibleForTesting (io.crate.common.annotations.VisibleForTesting)3 Symbol (io.crate.expression.symbol.Symbol)3 CoordinatorTxnCtx (io.crate.metadata.CoordinatorTxnCtx)3 ExpressionAnalysisContext (io.crate.analyze.expressions.ExpressionAnalysisContext)2 ExpressionAnalyzer (io.crate.analyze.expressions.ExpressionAnalyzer)2 TableReferenceResolver (io.crate.analyze.expressions.TableReferenceResolver)2 Lists2 (io.crate.common.collections.Lists2)2 GeoReference (io.crate.metadata.GeoReference)2 CrateDummyClusterServiceUnitTest (io.crate.test.integration.CrateDummyClusterServiceUnitTest)2 HashMap (java.util.HashMap)2 Map (java.util.Map)2 BytesReference (org.elasticsearch.common.bytes.BytesReference)2 Test (org.junit.Test)2 AnalyzedCopyTo (io.crate.analyze.AnalyzedCopyTo)1 BoundCopyTo (io.crate.analyze.BoundCopyTo)1