Search in sources :

Example 86 with SqlIdentifier

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlIdentifier in project samza by apache.

the class SamzaSqlQueryParser method getSource.

private static void getSource(SqlNode node, ArrayList<String> sourceList) {
    if (node instanceof SqlJoin) {
        SqlJoin joinNode = (SqlJoin) node;
        ArrayList<String> sourcesLeft = new ArrayList<>();
        ArrayList<String> sourcesRight = new ArrayList<>();
        getSource(joinNode.getLeft(), sourcesLeft);
        getSource(joinNode.getRight(), sourcesRight);
        sourceList.addAll(sourcesLeft);
        sourceList.addAll(sourcesRight);
    } else if (node instanceof SqlIdentifier) {
        sourceList.add(node.toString());
    } else if (node instanceof SqlBasicCall) {
        SqlBasicCall basicCall = (SqlBasicCall) node;
        if (basicCall.getOperator() instanceof SqlAsOperator) {
            getSource(basicCall.operand(0), sourceList);
        } else if (basicCall.getOperator() instanceof SqlUnnestOperator && basicCall.operand(0) instanceof SqlSelect) {
            sourceList.addAll(getSourcesFromSelectQuery(basicCall.operand(0)));
        }
    } else if (node instanceof SqlSelect) {
        getSource(((SqlSelect) node).getFrom(), sourceList);
    }
}
Also used : SqlSelect(org.apache.calcite.sql.SqlSelect) SqlBasicCall(org.apache.calcite.sql.SqlBasicCall) SqlJoin(org.apache.calcite.sql.SqlJoin) ArrayList(java.util.ArrayList) SqlUnnestOperator(org.apache.calcite.sql.SqlUnnestOperator) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlAsOperator(org.apache.calcite.sql.SqlAsOperator)

Example 87 with SqlIdentifier

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlIdentifier in project flink by apache.

the class HiveParserSqlFunctionConverter method getUDFInfo.

private static CalciteUDFInfo getUDFInfo(String hiveUdfName, List<RelDataType> calciteArgTypes, RelDataType calciteRetType) {
    CalciteUDFInfo udfInfo = new CalciteUDFInfo();
    udfInfo.udfName = hiveUdfName;
    String[] nameParts = hiveUdfName.split("\\.");
    if (nameParts.length > 1) {
        udfInfo.identifier = new SqlIdentifier(Arrays.stream(nameParts).collect(Collectors.toList()), new SqlParserPos(0, 0));
    }
    udfInfo.returnTypeInference = ReturnTypes.explicit(calciteRetType);
    udfInfo.operandTypeInference = InferTypes.explicit(calciteArgTypes);
    List<SqlTypeFamily> typeFamily = new ArrayList<>();
    for (RelDataType argType : calciteArgTypes) {
        typeFamily.add(Util.first(argType.getSqlTypeName().getFamily(), SqlTypeFamily.ANY));
    }
    udfInfo.operandTypeChecker = OperandTypes.family(Collections.unmodifiableList(typeFamily));
    return udfInfo;
}
Also used : SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) SqlTypeFamily(org.apache.calcite.sql.type.SqlTypeFamily) ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 88 with SqlIdentifier

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class SqlImplementor method addSelect.

public void addSelect(List<SqlNode> selectList, SqlNode node, RelDataType rowType) {
    String name = rowType.getFieldNames().get(selectList.size());
    String alias = SqlValidatorUtil.getAlias(node, -1);
    if (alias == null || !alias.equals(name)) {
        node = SqlStdOperatorTable.AS.createCall(POS, node, new SqlIdentifier(name, POS));
    }
    selectList.add(node);
}
Also used : DateString(org.apache.calcite.util.DateString) TimestampString(org.apache.calcite.util.TimestampString) TimeString(org.apache.calcite.util.TimeString) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier)

Example 89 with SqlIdentifier

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class SqlValidatorUtilTest method testCheckingDuplicatesWithCompoundIdentifiers.

@SuppressWarnings("resource")
@Test
public void testCheckingDuplicatesWithCompoundIdentifiers() {
    final List<SqlNode> newList = new ArrayList<>(2);
    newList.add(new SqlIdentifier(Arrays.asList("f0", "c0"), SqlParserPos.ZERO));
    newList.add(new SqlIdentifier(Arrays.asList("f0", "c0"), SqlParserPos.ZERO));
    final SqlTesterImpl tester = new SqlTesterImpl(DefaultSqlTestFactory.INSTANCE);
    final SqlValidatorImpl validator = (SqlValidatorImpl) tester.getValidator();
    try {
        SqlValidatorUtil.checkIdentifierListForDuplicates(newList, validator.getValidationErrorFunction());
        fail("expected exception");
    } catch (CalciteContextException e) {
    // ok
    }
    // should not throw
    newList.set(1, new SqlIdentifier(Arrays.asList("f0", "c1"), SqlParserPos.ZERO));
    SqlValidatorUtil.checkIdentifierListForDuplicates(newList, null);
}
Also used : CalciteContextException(org.apache.calcite.runtime.CalciteContextException) ArrayList(java.util.ArrayList) SqlTesterImpl(org.apache.calcite.sql.test.SqlTesterImpl) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) SqlNode(org.apache.calcite.sql.SqlNode) Test(org.junit.Test)

Example 90 with SqlIdentifier

use of org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.sql.SqlIdentifier in project calcite by apache.

the class DelegatingScope method fullyQualify.

/**
 * Converts an identifier into a fully-qualified identifier. For example,
 * the "empno" in "select empno from emp natural join dept" becomes
 * "emp.empno".
 *
 * <p>If the identifier cannot be resolved, throws. Never returns null.
 */
public SqlQualified fullyQualify(SqlIdentifier identifier) {
    if (identifier.isStar()) {
        return SqlQualified.create(this, 1, null, identifier);
    }
    final SqlIdentifier previous = identifier;
    final SqlNameMatcher nameMatcher = validator.catalogReader.nameMatcher();
    String columnName;
    final String tableName;
    final SqlValidatorNamespace namespace;
    switch(identifier.names.size()) {
        case 1:
            {
                columnName = identifier.names.get(0);
                final Map<String, ScopeChild> map = findQualifyingTableNames(columnName, identifier, nameMatcher);
                switch(map.size()) {
                    case 0:
                        if (nameMatcher.isCaseSensitive()) {
                            final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal();
                            final Map<String, ScopeChild> map2 = findQualifyingTableNames(columnName, identifier, liberalMatcher);
                            if (!map2.isEmpty()) {
                                final List<String> list = new ArrayList<>();
                                for (ScopeChild entry : map2.values()) {
                                    final RelDataTypeField field = liberalMatcher.field(entry.namespace.getRowType(), columnName);
                                    list.add(field.getName());
                                }
                                Collections.sort(list);
                                throw validator.newValidationError(identifier, RESOURCE.columnNotFoundDidYouMean(columnName, Util.sepList(list, "', '")));
                            }
                        }
                        throw validator.newValidationError(identifier, RESOURCE.columnNotFound(columnName));
                    case 1:
                        tableName = map.keySet().iterator().next();
                        namespace = map.get(tableName).namespace;
                        break;
                    default:
                        throw validator.newValidationError(identifier, RESOURCE.columnAmbiguous(columnName));
                }
                final ResolvedImpl resolved = new ResolvedImpl();
                resolveInNamespace(namespace, false, identifier.names, nameMatcher, Path.EMPTY, resolved);
                final RelDataTypeField field = nameMatcher.field(namespace.getRowType(), columnName);
                if (field != null) {
                    if (hasAmbiguousUnresolvedStar(namespace.getRowType(), field, columnName)) {
                        throw validator.newValidationError(identifier, RESOURCE.columnAmbiguous(columnName));
                    }
                    // use resolved field name
                    columnName = field.getName();
                }
                // todo: do implicit collation here
                final SqlParserPos pos = identifier.getParserPosition();
                identifier = new SqlIdentifier(ImmutableList.of(tableName, columnName), null, pos, ImmutableList.of(SqlParserPos.ZERO, pos));
            }
        // fall through
        default:
            {
                SqlValidatorNamespace fromNs = null;
                Path fromPath = null;
                RelDataType fromRowType = null;
                final ResolvedImpl resolved = new ResolvedImpl();
                int size = identifier.names.size();
                int i = size - 1;
                for (; i > 0; i--) {
                    final SqlIdentifier prefix = identifier.getComponent(0, i);
                    resolved.clear();
                    resolve(prefix.names, nameMatcher, false, resolved);
                    if (resolved.count() == 1) {
                        final Resolve resolve = resolved.only();
                        fromNs = resolve.namespace;
                        fromPath = resolve.path;
                        fromRowType = resolve.rowType();
                        break;
                    }
                    // Look for a table alias that is the wrong case.
                    if (nameMatcher.isCaseSensitive()) {
                        final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal();
                        resolved.clear();
                        resolve(prefix.names, liberalMatcher, false, resolved);
                        if (resolved.count() == 1) {
                            final Step lastStep = Util.last(resolved.only().path.steps());
                            throw validator.newValidationError(prefix, RESOURCE.tableNameNotFoundDidYouMean(prefix.toString(), lastStep.name));
                        }
                    }
                }
                if (fromNs == null || fromNs instanceof SchemaNamespace) {
                    // Look for a column not qualified by a table alias.
                    columnName = identifier.names.get(0);
                    final Map<String, ScopeChild> map = findQualifyingTableNames(columnName, identifier, nameMatcher);
                    switch(map.size()) {
                        default:
                            final SqlIdentifier prefix1 = identifier.skipLast(1);
                            throw validator.newValidationError(prefix1, RESOURCE.tableNameNotFound(prefix1.toString()));
                        case 1:
                            {
                                final Map.Entry<String, ScopeChild> entry = map.entrySet().iterator().next();
                                final String tableName2 = map.keySet().iterator().next();
                                fromNs = entry.getValue().namespace;
                                fromPath = Path.EMPTY;
                                // Adding table name is for RecordType column with StructKind.PEEK_FIELDS or
                                // StructKind.PEEK_FIELDS only. Access to a field in a RecordType column of
                                // other StructKind should always be qualified with table name.
                                final RelDataTypeField field = nameMatcher.field(fromNs.getRowType(), columnName);
                                if (field != null) {
                                    switch(field.getType().getStructKind()) {
                                        case PEEK_FIELDS:
                                        case PEEK_FIELDS_DEFAULT:
                                        case PEEK_FIELDS_NO_EXPAND:
                                            // use resolved field name
                                            columnName = field.getName();
                                            resolve(ImmutableList.of(tableName2), nameMatcher, false, resolved);
                                            if (resolved.count() == 1) {
                                                final Resolve resolve = resolved.only();
                                                fromNs = resolve.namespace;
                                                fromPath = resolve.path;
                                                fromRowType = resolve.rowType();
                                                identifier = identifier.setName(0, columnName).add(0, tableName2, SqlParserPos.ZERO);
                                                ++i;
                                                ++size;
                                            }
                                            break;
                                        default:
                                            // Throw an error if the table was not found.
                                            // If one or more of the child namespaces allows peeking
                                            // (e.g. if they are Phoenix column families) then we relax the SQL
                                            // standard requirement that record fields are qualified by table alias.
                                            final SqlIdentifier prefix = identifier.skipLast(1);
                                            throw validator.newValidationError(prefix, RESOURCE.tableNameNotFound(prefix.toString()));
                                    }
                                }
                            }
                    }
                }
                // change "e.empno" to "E.empno".
                if (fromNs.getEnclosingNode() != null && !(this instanceof MatchRecognizeScope)) {
                    String alias = SqlValidatorUtil.getAlias(fromNs.getEnclosingNode(), -1);
                    if (alias != null && i > 0 && !alias.equals(identifier.names.get(i - 1))) {
                        identifier = identifier.setName(i - 1, alias);
                    }
                }
                if (fromPath.stepCount() > 1) {
                    assert fromRowType != null;
                    for (Step p : fromPath.steps()) {
                        fromRowType = fromRowType.getFieldList().get(p.i).getType();
                    }
                    ++i;
                }
                final SqlIdentifier suffix = identifier.getComponent(i, size);
                resolved.clear();
                resolveInNamespace(fromNs, false, suffix.names, nameMatcher, Path.EMPTY, resolved);
                final Path path;
                switch(resolved.count()) {
                    case 0:
                        // Maybe the last component was correct, just wrong case
                        if (nameMatcher.isCaseSensitive()) {
                            SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal();
                            resolved.clear();
                            resolveInNamespace(fromNs, false, suffix.names, liberalMatcher, Path.EMPTY, resolved);
                            if (resolved.count() > 0) {
                                int k = size - 1;
                                final SqlIdentifier prefix = identifier.getComponent(0, i);
                                final SqlIdentifier suffix3 = identifier.getComponent(i, k + 1);
                                final Step step = Util.last(resolved.resolves.get(0).path.steps());
                                throw validator.newValidationError(suffix3, RESOURCE.columnNotFoundInTableDidYouMean(suffix3.toString(), prefix.toString(), step.name));
                            }
                        }
                        // Find the shortest suffix that also fails. Suppose we cannot resolve
                        // "a.b.c"; we find we cannot resolve "a.b" but can resolve "a". So,
                        // the error will be "Column 'a.b' not found".
                        int k = size - 1;
                        for (; k > i; --k) {
                            SqlIdentifier suffix2 = identifier.getComponent(i, k);
                            resolved.clear();
                            resolveInNamespace(fromNs, false, suffix2.names, nameMatcher, Path.EMPTY, resolved);
                            if (resolved.count() > 0) {
                                break;
                            }
                        }
                        final SqlIdentifier prefix = identifier.getComponent(0, i);
                        final SqlIdentifier suffix3 = identifier.getComponent(i, k + 1);
                        throw validator.newValidationError(suffix3, RESOURCE.columnNotFoundInTable(suffix3.toString(), prefix.toString()));
                    case 1:
                        path = resolved.only().path;
                        break;
                    default:
                        final Comparator<Resolve> c = new Comparator<Resolve>() {

                            public int compare(Resolve o1, Resolve o2) {
                                // Name resolution that uses fewer implicit steps wins.
                                int c = Integer.compare(worstKind(o1.path), worstKind(o2.path));
                                if (c != 0) {
                                    return c;
                                }
                                // Shorter path wins
                                return Integer.compare(o1.path.stepCount(), o2.path.stepCount());
                            }

                            private int worstKind(Path path) {
                                int kind = -1;
                                for (Step step : path.steps()) {
                                    kind = Math.max(kind, step.kind.ordinal());
                                }
                                return kind;
                            }
                        };
                        Collections.sort(resolved.resolves, c);
                        if (c.compare(resolved.resolves.get(0), resolved.resolves.get(1)) == 0) {
                            throw validator.newValidationError(suffix, RESOURCE.columnAmbiguous(suffix.toString()));
                        }
                        path = resolved.resolves.get(0).path;
                }
                // Normalize case to match definition, make elided fields explicit,
                // and check that references to dynamic stars ("**") are unambiguous.
                int k = i;
                for (Step step : path.steps()) {
                    final String name = identifier.names.get(k);
                    if (step.i < 0) {
                        throw validator.newValidationError(identifier, RESOURCE.columnNotFound(name));
                    }
                    final RelDataTypeField field0 = step.rowType.getFieldList().get(step.i);
                    final String fieldName = field0.getName();
                    switch(step.kind) {
                        case PEEK_FIELDS:
                        case PEEK_FIELDS_DEFAULT:
                        case PEEK_FIELDS_NO_EXPAND:
                            identifier = identifier.add(k, fieldName, SqlParserPos.ZERO);
                            break;
                        default:
                            if (!fieldName.equals(name)) {
                                identifier = identifier.setName(k, fieldName);
                            }
                            if (hasAmbiguousUnresolvedStar(step.rowType, field0, name)) {
                                throw validator.newValidationError(identifier, RESOURCE.columnAmbiguous(name));
                            }
                    }
                    ++k;
                }
                // CustomResolvingTable.
                if (identifier.names.size() > k) {
                    identifier = identifier.getComponent(0, k);
                }
                if (i > 1) {
                    // Simplify overqualified identifiers.
                    // For example, schema.emp.deptno becomes emp.deptno.
                    // 
                    // It is safe to convert schema.emp or database.schema.emp to emp
                    // because it would not have resolved if the FROM item had an alias. The
                    // following query is invalid:
                    // SELECT schema.emp.deptno FROM schema.emp AS e
                    identifier = identifier.getComponent(i - 1, identifier.names.size());
                }
                if (!previous.equals(identifier)) {
                    validator.setOriginal(identifier, previous);
                }
                return SqlQualified.create(this, i, fromNs, identifier);
            }
    }
}
Also used : SqlParserPos(org.apache.calcite.sql.parser.SqlParserPos) RelDataType(org.apache.calcite.rel.type.RelDataType) SqlIdentifier(org.apache.calcite.sql.SqlIdentifier) Comparator(java.util.Comparator) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) ArrayList(java.util.ArrayList) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) SqlNodeList(org.apache.calcite.sql.SqlNodeList) Map(java.util.Map)

Aggregations

SqlIdentifier (org.apache.calcite.sql.SqlIdentifier)131 SqlNode (org.apache.calcite.sql.SqlNode)84 RelDataType (org.apache.calcite.rel.type.RelDataType)46 SqlNodeList (org.apache.calcite.sql.SqlNodeList)43 ArrayList (java.util.ArrayList)41 SqlCall (org.apache.calcite.sql.SqlCall)32 BitString (org.apache.calcite.util.BitString)28 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)21 SqlSelect (org.apache.calcite.sql.SqlSelect)21 SqlParserPos (org.apache.calcite.sql.parser.SqlParserPos)12 SchemaPlus (org.apache.calcite.schema.SchemaPlus)11 SqlOperator (org.apache.calcite.sql.SqlOperator)11 NlsString (org.apache.calcite.util.NlsString)11 List (java.util.List)9 Map (java.util.Map)9 RelOptTable (org.apache.calcite.plan.RelOptTable)9 RexNode (org.apache.calcite.rex.RexNode)9 AbstractSchema (org.apache.drill.exec.store.AbstractSchema)9 ImmutableList (com.google.common.collect.ImmutableList)8 RelNode (org.apache.calcite.rel.RelNode)7