@Override public int[] computeLogicalKeyPositions() { List<Integer> logicalKeys = new ArrayList<>(); for (FlatFieldDescriptor kd : keyFields) { logicalKeys.add(kd.getPosition()); } return Ints.toArray(logicalKeys); }
/** Create String-based (nested) field expression keys on a composite type. */ public ExpressionKeys(String[] keyExpressions, TypeInformation<T> type) { Preconditions.checkNotNull(keyExpressions, "Field expression cannot be null."); this.keyFields = new ArrayList<>(keyExpressions.length); if (type instanceof CompositeType) { CompositeType<T> cType = (CompositeType<T>) type; // extract the keys on their flat position for (String keyExpr : keyExpressions) { if (keyExpr == null) { throw new InvalidProgramException("Expression key may not be null."); } // strip off whitespace keyExpr = keyExpr.trim(); List<FlatFieldDescriptor> flatFields = cType.getFlatFields(keyExpr); if (flatFields.size() == 0) { throw new InvalidProgramException( "Unable to extract key from expression '" + keyExpr + "' on key " + cType); } // check if all nested fields can be used as keys for (FlatFieldDescriptor field : flatFields) { if (!field.getType().isKeyType()) { throw new InvalidProgramException( "This type (" + field.getType() + ") cannot be used as key."); } } // add flat fields to key fields keyFields.addAll(flatFields); } } else { if (!type.isKeyType()) { throw new InvalidProgramException("This type (" + type + ") cannot be used as key."); } // check that all key expressions are valid for (String keyExpr : keyExpressions) { if (keyExpr == null) { throw new InvalidProgramException("Expression key may not be null."); } // strip off whitespace keyExpr = keyExpr.trim(); // check that full type is addressed if (!(SELECT_ALL_CHAR.equals(keyExpr) || SELECT_ALL_CHAR_SCALA.equals(keyExpr))) { throw new InvalidProgramException( "Field expression must be equal to '" + SELECT_ALL_CHAR + "' or '" + SELECT_ALL_CHAR_SCALA + "' for non-composite types."); } // add full type as key keyFields.add(new FlatFieldDescriptor(0, type)); } } }
/** Create int-based (non-nested) field position keys on a tuple type. */ public ExpressionKeys(int[] keyPositions, TypeInformation<T> type, boolean allowEmpty) { if (!type.isTupleType() || !(type instanceof CompositeType)) { throw new InvalidProgramException( "Specifying keys via field positions is only valid " + "for tuple data types. Type: " + type); } if (type.getArity() == 0) { throw new InvalidProgramException( "Tuple size must be greater than 0. Size: " + type.getArity()); } if (!allowEmpty && (keyPositions == null || keyPositions.length == 0)) { throw new IllegalArgumentException("The grouping fields must not be empty."); } this.keyFields = new ArrayList<>(); if (keyPositions == null || keyPositions.length == 0) { // use all tuple fields as key fields keyPositions = createIncrIntArray(type.getArity()); } else { rangeCheckFields(keyPositions, type.getArity() - 1); } Preconditions.checkArgument( keyPositions.length > 0, "Grouping fields can not be empty at this point"); // extract key field types CompositeType<T> cType = (CompositeType<T>) type; this.keyFields = new ArrayList<>(type.getTotalFields()); // for each key position, find all (nested) field types String[] fieldNames = cType.getFieldNames(); ArrayList<FlatFieldDescriptor> tmpList = new ArrayList<>(); for (int keyPos : keyPositions) { tmpList.clear(); // get all flat fields cType.getFlatFields(fieldNames[keyPos], 0, tmpList); // check if fields are of key type for (FlatFieldDescriptor ffd : tmpList) { if (!ffd.getType().isKeyType()) { throw new InvalidProgramException( "This type (" + ffd.getType() + ") cannot be used as key."); } } this.keyFields.addAll(tmpList); } }
/** Create ExpressionKeys from String-expressions */ public ExpressionKeys(String[] expressionsIn, TypeInformation<T> type) { Preconditions.checkNotNull(expressionsIn, "Field expression cannot be null."); if (type instanceof AtomicType) { if (!type.isKeyType()) { throw new InvalidProgramException("This type (" + type + ") cannot be used as key."); } else if (expressionsIn.length != 1 || !(Keys.ExpressionKeys.SELECT_ALL_CHAR.equals(expressionsIn[0]) || Keys.ExpressionKeys.SELECT_ALL_CHAR_SCALA.equals(expressionsIn[0]))) { throw new InvalidProgramException( "Field expression for atomic type must be equal to '*' or '_'."); } keyFields = new ArrayList<>(1); keyFields.add(new FlatFieldDescriptor(0, type)); } else { CompositeType<T> cType = (CompositeType<T>) type; String[] expressions = removeDuplicates(expressionsIn); if (expressionsIn.length != expressions.length) { LOG.warn("The key expressions contained duplicates. They are now unique"); } // extract the keys on their flat position keyFields = new ArrayList<>(expressions.length); for (String expression : expressions) { List<FlatFieldDescriptor> keys = cType.getFlatFields(expression); // use separate list to do a size check for (FlatFieldDescriptor key : keys) { TypeInformation<?> keyType = key.getType(); if (!keyType.isKeyType()) { throw new InvalidProgramException( "This type (" + key.getType() + ") cannot be used as key."); } if (!(keyType instanceof AtomicType || keyType instanceof CompositeType)) { throw new InvalidProgramException( "Field type is neither CompositeType nor AtomicType: " + keyType); } } if (keys.size() == 0) { throw new InvalidProgramException( "Unable to extract key from expression '" + expression + "' on key " + cType); } keyFields.addAll(keys); } } }