private void checkRollUpInUsing(SqlIdentifier identifier, SqlNode leftOrRight) { leftOrRight = stripAs(leftOrRight); // if it's not a SqlIdentifier then that's fine, it'll be validated somewhere else. if (leftOrRight instanceof SqlIdentifier) { SqlIdentifier from = (SqlIdentifier) leftOrRight; Table table = findTable(catalogReader.getRootSchema(), Util.last(from.names), catalogReader.nameMatcher().isCaseSensitive()); String name = Util.last(identifier.names); if (table != null && table.isRolledUp(name)) { throw newValidationError(identifier, RESOURCE.rolledUpNotAllowed(name, "USING")); } } }
private RelDataTypeField field(String name) { return catalogReader.nameMatcher().field(rowType, name); }
private RelDataType validateUsingCol(SqlIdentifier id, SqlNode leftOrRight) { if (id.names.size() == 1) { String name = id.names.get(0); final SqlValidatorNamespace namespace = getNamespace(leftOrRight); final RelDataType rowType = namespace.getRowType(); final SqlNameMatcher nameMatcher = catalogReader.nameMatcher(); final RelDataTypeField field = nameMatcher.field(rowType, name); if (field != null) { if (nameMatcher.frequency(rowType.getFieldNames(), name) > 1) { throw newValidationError(id, RESOURCE.columnInUsingNotUnique(id.toString())); } return field.getType(); } } throw newValidationError(id, RESOURCE.columnNotFound(id.toString())); }
/** * Given a table alias, find the corresponding {@link Table} associated with it * */ private Table findTable(String alias) { List<String> names = null; if (tableScope == null) { // no tables to find return null; } for (ScopeChild child : tableScope.children) { if (catalogReader.nameMatcher().matches(child.name, alias)) { names = ((SqlIdentifier) child.namespace.getNode()).names; break; } } if (names == null || names.size() == 0) { return null; } else if (names.size() == 1) { return findTable(catalogReader.getRootSchema(), names.get(0), catalogReader.nameMatcher().isCaseSensitive()); } CalciteSchema.TableEntry entry = SqlValidatorUtil.getTableEntry(catalogReader, names); return entry == null ? null : entry.getTable(); }
switch (map.size()) { case 0: if (nameMatcher.isCaseSensitive()) { final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); final Map<String, ScopeChild> map2 = for (ScopeChild entry : map2.values()) { final RelDataTypeField field = liberalMatcher.field(entry.namespace.getRowType(), columnName); list.add(field.getName()); Path.EMPTY, resolved); final RelDataTypeField field = nameMatcher.field(namespace.getRowType(), columnName); if (field != null) { if (hasAmbiguousUnresolvedStar(namespace.getRowType(), field, if (nameMatcher.isCaseSensitive()) { final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); resolved.clear(); nameMatcher.field(fromNs.getRowType(), columnName); if (field != null) { switch (field.getType().getStructKind()) { if (nameMatcher.isCaseSensitive()) { SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); resolved.clear();
for (SqlNode s : select.getSelectList()) { final String alias = SqlValidatorUtil.getAlias(s, -1); if (alias != null && nameMatcher.matches(alias, name)) { expr = s; n++;
/** * Derives the list of column names suitable for NATURAL JOIN. These are the * columns that occur exactly once on each side of the join. * * @param nameMatcher Whether matches are case-sensitive * @param leftRowType Row type of left input to the join * @param rightRowType Row type of right input to the join * @return List of columns that occur once on each side */ public static List<String> deriveNaturalJoinColumnList( SqlNameMatcher nameMatcher, RelDataType leftRowType, RelDataType rightRowType) { final List<String> naturalColumnNames = new ArrayList<>(); final List<String> leftNames = leftRowType.getFieldNames(); final List<String> rightNames = rightRowType.getFieldNames(); for (String name : leftNames) { if (nameMatcher.frequency(leftNames, name) == 1 && nameMatcher.frequency(rightNames, name) == 1) { naturalColumnNames.add(name); } } return naturalColumnNames; }
/** Returns the set of field names in the join condition specified by USING * or implicitly by NATURAL, de-duplicated and in order. */ private List<String> usingNames(SqlJoin join) { switch (join.getConditionType()) { case USING: final ImmutableList.Builder<String> list = ImmutableList.builder(); final Set<String> names = catalogReader.nameMatcher().createSet(); for (SqlNode node : (SqlNodeList) join.getCondition()) { final String name = ((SqlIdentifier) node).getSimple(); if (names.add(name)) { list.add(name); } } return list.build(); case NONE: if (join.isNatural()) { final RelDataType t0 = getValidatedNodeType(join.getLeft()); final RelDataType t1 = getValidatedNodeType(join.getRight()); return SqlValidatorUtil.deriveNaturalJoinColumnList( catalogReader.nameMatcher(), t0, t1); } } return null; }
/** * Finds and returns {@link CalciteSchema} nested to the given rootSchema * with specified schemaPath. * * <p>Uses the case-sensitivity policy of specified nameMatcher. * * <p>If not found, returns null. * * @param rootSchema root schema * @param schemaPath full schema path of required schema * @param nameMatcher name matcher * * @return CalciteSchema that corresponds specified schemaPath */ public static CalciteSchema getSchema(CalciteSchema rootSchema, Iterable<String> schemaPath, SqlNameMatcher nameMatcher) { CalciteSchema schema = rootSchema; for (String schemaName : schemaPath) { if (schema == rootSchema && nameMatcher.matches(schemaName, schema.getName())) { continue; } schema = schema.getSubSchema(schemaName, nameMatcher.isCaseSensitive()); if (schema == null) { return null; } } return schema; }
switch (map.size()) { case 0: if (nameMatcher.isCaseSensitive()) { final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); final Map<String, ScopeChild> map2 = for (ScopeChild entry : map2.values()) { final RelDataTypeField field = liberalMatcher.field(entry.namespace.getRowType(), columnName); list.add(field.getName()); Path.EMPTY, resolved); final RelDataTypeField field = nameMatcher.field(namespace.getRowType(), columnName); if (field != null) { if (hasAmbiguousUnresolvedStar(namespace.getRowType(), field, if (nameMatcher.isCaseSensitive()) { final SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); resolved.clear(); nameMatcher.field(fromNs.getRowType(), columnName); if (field != null) { switch (field.getType().getStructKind()) { if (nameMatcher.isCaseSensitive()) { SqlNameMatcher liberalMatcher = SqlNameMatchers.liberal(); resolved.clear();
@SuppressWarnings("deprecation") public boolean matches(String string, String name) { return nameMatcher.matches(string, name); }
/** * Derives the list of column names suitable for NATURAL JOIN. These are the * columns that occur exactly once on each side of the join. * * @param nameMatcher Whether matches are case-sensitive * @param leftRowType Row type of left input to the join * @param rightRowType Row type of right input to the join * @return List of columns that occur once on each side */ public static List<String> deriveNaturalJoinColumnList( SqlNameMatcher nameMatcher, RelDataType leftRowType, RelDataType rightRowType) { final List<String> naturalColumnNames = new ArrayList<>(); final List<String> leftNames = leftRowType.getFieldNames(); final List<String> rightNames = rightRowType.getFieldNames(); for (String name : leftNames) { if (nameMatcher.frequency(leftNames, name) == 1 && nameMatcher.frequency(rightNames, name) == 1) { naturalColumnNames.add(name); } } return naturalColumnNames; }
public SqlNodeList expandStar( SqlNodeList selectList, SqlSelect select, boolean includeSystemVars) { final List<SqlNode> list = new ArrayList<>(); final List<Map.Entry<String, RelDataType>> types = new ArrayList<>(); for (int i = 0; i < selectList.size(); i++) { final SqlNode selectItem = selectList.get(i); final RelDataType originalType = getValidatedNodeTypeIfKnown(selectItem); expandSelectItem( selectItem, select, Util.first(originalType, unknownType), list, catalogReader.nameMatcher().createSet(), types, includeSystemVars); } getRawSelectScope(select).setExpandedSelectList(list); return new SqlNodeList(list, SqlParserPos.ZERO); }
if (!catalogReader.nameMatcher().isCaseSensitive()) { names = Lists.transform(names, s -> s.toUpperCase(Locale.ROOT));
SqlValidatorNamespace lookupFieldNamespace(RelDataType rowType, String name) { final SqlNameMatcher nameMatcher = catalogReader.nameMatcher(); final RelDataTypeField field = nameMatcher.field(rowType, name); return new FieldNamespace(this, field.getType()); }
/** * Finds and returns {@link CalciteSchema} nested to the given rootSchema * with specified schemaPath. * * <p>Uses the case-sensitivity policy of specified nameMatcher. * * <p>If not found, returns null. * * @param rootSchema root schema * @param schemaPath full schema path of required schema * @param nameMatcher name matcher * * @return CalciteSchema that corresponds specified schemaPath */ public static CalciteSchema getSchema(CalciteSchema rootSchema, Iterable<String> schemaPath, SqlNameMatcher nameMatcher) { CalciteSchema schema = rootSchema; for (String schemaName : schemaPath) { if (schema == rootSchema && nameMatcher.matches(schemaName, schema.getName())) { continue; } schema = schema.getSubSchema(schemaName, nameMatcher.isCaseSensitive()); if (schema == null) { return null; } } return schema; }
private RelDataType validateUsingCol(SqlIdentifier id, SqlNode leftOrRight) { if (id.names.size() == 1) { String name = id.names.get(0); final SqlValidatorNamespace namespace = getNamespace(leftOrRight); final RelDataType rowType = namespace.getRowType(); final SqlNameMatcher nameMatcher = catalogReader.nameMatcher(); final RelDataTypeField field = nameMatcher.field(rowType, name); if (field != null) { if (nameMatcher.frequency(rowType.getFieldNames(), name) > 1) { throw newValidationError(id, RESOURCE.columnInUsingNotUnique(id.toString())); } return field.getType(); } } throw newValidationError(id, RESOURCE.columnNotFound(id.toString())); }
@SuppressWarnings("deprecation") public boolean matches(String string, String name) { return nameMatcher.matches(string, name); }
@Test public void testNameMatcher() { final ImmutableList<String> beatles = ImmutableList.of("john", "paul", "ringo", "rinGo"); final SqlNameMatcher insensitiveMatcher = SqlNameMatchers.withCaseSensitive(false); assertThat(insensitiveMatcher.frequency(beatles, "ringo"), is(2)); assertThat(insensitiveMatcher.frequency(beatles, "rinGo"), is(2)); final SqlNameMatcher sensitiveMatcher = SqlNameMatchers.withCaseSensitive(true); assertThat(sensitiveMatcher.frequency(beatles, "ringo"), is(1)); assertThat(sensitiveMatcher.frequency(beatles, "rinGo"), is(1)); assertThat(sensitiveMatcher.frequency(beatles, "Ringo"), is(0)); } }
private void validateDefinitions(SqlMatchRecognize mr, MatchRecognizeScope scope) { final Set<String> aliases = catalogReader.nameMatcher().createSet(); for (SqlNode item : mr.getPatternDefList().getList()) { final String alias = alias(item);