@Override
    public void getFlatFields(
            String fieldExpression, int offset, List<FlatFieldDescriptor> result) {
        Matcher matcher = PATTERN_NESTED_FIELDS_WILDCARD.matcher(fieldExpression);

        if (!matcher.matches()) {
            throw new InvalidFieldReferenceException(
                    "Invalid tuple field reference \"" + fieldExpression + "\".");
        }

        String field = matcher.group(0);

        if ((field.equals(ExpressionKeys.SELECT_ALL_CHAR))
                || (field.equals(ExpressionKeys.SELECT_ALL_CHAR_SCALA))) {
            // handle select all
            int keyPosition = 0;
            for (TypeInformation<?> fType : types) {
                if (fType instanceof CompositeType) {
                    CompositeType<?> cType = (CompositeType<?>) fType;
                    cType.getFlatFields(
                            ExpressionKeys.SELECT_ALL_CHAR, offset + keyPosition, result);
                    keyPosition += cType.getTotalFields() - 1;
                } else {
                    result.add(new FlatFieldDescriptor(offset + keyPosition, fType));
                }
                keyPosition++;
            }
        } else {
            field = matcher.group(1);

            Matcher intFieldMatcher = PATTERN_INT_FIELD.matcher(field);
            int fieldIndex;
            if (intFieldMatcher.matches()) {
                // field expression is an integer
                fieldIndex = Integer.valueOf(field);
            } else {
                fieldIndex = this.getFieldIndex(field);
            }
            // fetch the field type will throw exception if the index is illegal
            TypeInformation<?> fieldType = this.getTypeAt(fieldIndex);
            // compute the offset,
            for (int i = 0; i < fieldIndex; i++) {
                offset += this.getTypeAt(i).getTotalFields();
            }

            String tail = matcher.group(3);

            if (tail == null) {
                // expression hasn't nested field
                if (fieldType instanceof CompositeType) {
                    ((CompositeType) fieldType).getFlatFields("*", offset, result);
                } else {
                    result.add(new FlatFieldDescriptor(offset, fieldType));
                }
            } else {
                // expression has nested field
                if (fieldType instanceof CompositeType) {
                    ((CompositeType) fieldType).getFlatFields(tail, offset, result);
                } else {
                    throw new InvalidFieldReferenceException(
                            "Nested field expression \""
                                    + tail
                                    + "\" not possible on atomic type "
                                    + fieldType
                                    + ".");
                }
            }
        }
    }
@Test
    void testGetFlatFields() {
        RowTypeInfo typeInfo1 = new RowTypeInfo(typeList, new String[] {"int", "row", "string"});
        List<FlatFieldDescriptor> result = new ArrayList<>();
        typeInfo1.getFlatFields("row.*", 0, result);
        assertThat(result).hasSize(2);
        assertThat(result.get(0).toString())
                .isEqualTo(new FlatFieldDescriptor(1, BasicTypeInfo.SHORT_TYPE_INFO).toString());
        assertThat(result.get(1).toString())
                .isEqualTo(new FlatFieldDescriptor(2, BasicTypeInfo.BIG_DEC_TYPE_INFO).toString());

        result.clear();
        typeInfo1.getFlatFields("string", 0, result);
        assertThat(result).hasSize(1);
        assertThat(result.get(0).toString())
                .isEqualTo(new FlatFieldDescriptor(3, BasicTypeInfo.STRING_TYPE_INFO).toString());
    }