Search in sources :

Example 1 with AmbiguousColumnException

use of io.crate.exceptions.AmbiguousColumnException in project crate by crate.

the class FullQualifiedNameFieldProvider method resolveField.

@Override
public Symbol resolveField(QualifiedName qualifiedName, @Nullable List<String> path, Operation operation, boolean errorOnUnknownObjectKey) {
    List<String> parts = qualifiedName.getParts();
    String columnSchema = null;
    String columnTableName = null;
    ColumnIdent columnIdent = new ColumnIdent(parts.get(parts.size() - 1), path);
    switch(parts.size()) {
        case 1:
            break;
        case 2:
            columnTableName = parts.get(0);
            break;
        case 3:
            columnSchema = parts.get(0);
            columnTableName = parts.get(1);
            break;
        default:
            throw new IllegalArgumentException("Column reference \"%s\" has too many parts. " + "A column reference can have at most 3 parts and must have one of the following formats:  " + "\"<column>\", \"<table>.<column>\" or \"<schema>.<table>.<column>\"");
    }
    boolean schemaMatched = false;
    boolean tableNameMatched = false;
    Symbol lastField = null;
    for (var entry : sources.entrySet()) {
        RelationName relName = entry.getKey();
        String sourceSchema = relName.schema();
        String sourceTableOrAlias = relName.name();
        if (columnSchema != null && !columnSchema.equals(sourceSchema)) {
            continue;
        }
        schemaMatched = true;
        if (columnTableName != null && !sourceTableOrAlias.equals(columnTableName)) {
            continue;
        }
        tableNameMatched = true;
        AnalyzedRelation sourceRelation = entry.getValue();
        Symbol newField = sourceRelation.getField(columnIdent, operation, errorOnUnknownObjectKey);
        if (newField != null) {
            if (lastField != null) {
                if (errorOnUnknownObjectKey == false) {
                    /* ex) CREATE TABLE c1 (obj object as (x int));
                         *     CREATE TABLE c2 (obj object as (y int));
                         *     select obj['x'] from c1, c2;
                         *     --> ambiguous because c2.obj['x'] is another candidate with errorOnUnknownObjectKey = false
                         */
                    return resolveField(qualifiedName, path, operation, true);
                }
                throw new AmbiguousColumnException(columnIdent, newField);
            }
            lastField = newField;
        }
    }
    if (lastField == null) {
        if (!schemaMatched || !tableNameMatched) {
            String schema = columnSchema == null ? defaultSchema : columnSchema;
            raiseUnsupportedFeatureIfInParentScope(columnSchema, columnTableName, schema);
            RelationName relationName = new RelationName(schema, columnTableName);
            throw new RelationUnknown(relationName);
        }
        RelationName relationName = sources.entrySet().iterator().next().getKey();
        throw new ColumnUnknownException(columnIdent.sqlFqn(), relationName);
    }
    return lastField;
}
Also used : ColumnIdent(io.crate.metadata.ColumnIdent) RelationUnknown(io.crate.exceptions.RelationUnknown) ColumnUnknownException(io.crate.exceptions.ColumnUnknownException) Symbol(io.crate.expression.symbol.Symbol) RelationName(io.crate.metadata.RelationName) AmbiguousColumnException(io.crate.exceptions.AmbiguousColumnException)

Example 2 with AmbiguousColumnException

use of io.crate.exceptions.AmbiguousColumnException in project crate by crate.

the class FullQualifedNameFieldProvider method resolveField.

public Field resolveField(QualifiedName qualifiedName, @Nullable List<String> path, Operation operation) {
    List<String> parts = qualifiedName.getParts();
    String columnSchema = null;
    String columnTableName = null;
    ColumnIdent columnIdent = new ColumnIdent(parts.get(parts.size() - 1), path);
    switch(parts.size()) {
        case 1:
            break;
        case 2:
            columnTableName = parts.get(0);
            break;
        case 3:
            columnSchema = parts.get(0);
            columnTableName = parts.get(1);
            break;
        default:
            throw new IllegalArgumentException("Column reference \"%s\" has too many parts. " + "A column reference can have at most 3 parts and must have one of the following formats:  " + "\"<column>\", \"<table>.<column>\" or \"<schema>.<table>.<column>\"");
    }
    boolean schemaMatched = false;
    boolean tableNameMatched = false;
    Field lastField = null;
    for (Map.Entry<QualifiedName, AnalyzedRelation> entry : sources.entrySet()) {
        List<String> sourceParts = entry.getKey().getParts();
        String sourceSchema = null;
        String sourceTableOrAlias;
        if (sourceParts.size() == 1) {
            sourceTableOrAlias = sourceParts.get(0);
        } else if (sourceParts.size() == 2) {
            sourceSchema = sourceParts.get(0);
            sourceTableOrAlias = sourceParts.get(1);
        } else {
            throw new UnsupportedOperationException(String.format(Locale.ENGLISH, "sources key (QualifiedName) must have 1 or 2 parts, not %d", sourceParts.size()));
        }
        AnalyzedRelation sourceRelation = entry.getValue();
        if (columnSchema != null && sourceSchema != null && !columnSchema.equals(sourceSchema)) {
            continue;
        }
        schemaMatched = true;
        if (columnTableName != null && !sourceTableOrAlias.equals(columnTableName)) {
            continue;
        }
        tableNameMatched = true;
        Field newField = sourceRelation.getField(columnIdent, operation);
        if (newField != null) {
            if (lastField != null) {
                throw new AmbiguousColumnException(columnIdent);
            }
            lastField = newField;
        }
    }
    if (lastField == null) {
        if (!schemaMatched || !tableNameMatched) {
            throw RelationUnknownException.of(columnSchema, columnTableName);
        }
        throw new ColumnUnknownException(columnIdent.sqlFqn());
    }
    return lastField;
}
Also used : QualifiedName(io.crate.sql.tree.QualifiedName) ColumnIdent(io.crate.metadata.ColumnIdent) Field(io.crate.analyze.symbol.Field) ColumnUnknownException(io.crate.exceptions.ColumnUnknownException) AmbiguousColumnException(io.crate.exceptions.AmbiguousColumnException) Map(java.util.Map)

Aggregations

AmbiguousColumnException (io.crate.exceptions.AmbiguousColumnException)2 ColumnUnknownException (io.crate.exceptions.ColumnUnknownException)2 ColumnIdent (io.crate.metadata.ColumnIdent)2 Field (io.crate.analyze.symbol.Field)1 RelationUnknown (io.crate.exceptions.RelationUnknown)1 Symbol (io.crate.expression.symbol.Symbol)1 RelationName (io.crate.metadata.RelationName)1 QualifiedName (io.crate.sql.tree.QualifiedName)1 Map (java.util.Map)1