EntityViewsData::mapFieldDefinition has the following code:
// Add all properties to views table data. We need an entry for each
// column of each field, with the first one given special treatment.
// @todo Introduce concept of the "main" column for a field, rather than
// assuming the first one is the main column. See also what the
// mapSingleFieldViewsData() method does with $first.
$first = TRUE;
foreach ($field_column_mapping as $field_column_name => $schema_field_name) {
$table_data[$schema_field_name] = $this->mapSingleFieldViewsData($table, $field_name, $field_definition_type, $field_column_name, $field_schema['columns'][$field_column_name]['type'], $first, $field_definition);
$table_data[$schema_field_name]['entity field'] = $field_name;
$first = FALSE;
}
It continues in mapSingleFieldViewsData:
// Provide a nicer, less verbose label for the first column within a field.
// @todo Introduce concept of the "main" column for a field, rather than
// assuming the first one is the main column.
if ($first) {
$views_field['title'] = $field_definition->getLabel();
}
else {
$views_field['title'] = $field_definition->getLabel() . " ($column_name)";
}
$field_storage->getMainPropertyName() is not used because it didn't exist at the time.
The resulting views data is broken for:
1) Fields with no main property name
2) Fields with multiple properties whose main property is not the first one
What happens in case of #1 is that the first random property gets promoted to main, so it can't be used separately anymore.
For address fields this is the "langcode" field. For price fields this is the "number" field.
Instead, when the main property name is NULL, we should be adding a pseudo-field whose only purpose is to render the field.
That will keep access to the individual properties intact.