Fix cell path when getting columns of non-records (#7508)

A follow-up to #7497. That change made it so that `get foo` would
eliminate non-record rows; I think that was an unintentional and
undesirable side-effect.

Before #7497:
```bash
〉[$nothing, { item: "foo" }] | get item
╭───┬─────╮
│ 0 │     │
│ 1 │ foo │
╰───┴─────╯
```
After #7497:
```bash
〉[$nothing, {item: "foo"}] | get item
╭───┬─────╮
│ 0 │ foo │
╰───┴─────╯
```

After this PR:
```bash
〉[$nothing, { item: "foo" }] | get item
╭───┬─────╮
│ 0 │     │
│ 1 │ foo │
╰───┴─────╯
```

cc: @merelymyself
This commit is contained in:
Reilly Wood 2022-12-17 09:14:12 -08:00 committed by GitHub
parent 0826e66fe0
commit 705f12c1d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 16 deletions

View File

@ -179,7 +179,7 @@ fn parses_json() {
fn parses_xml() {
let actual = nu!(
cwd: "tests/fixtures/formats",
"open jonathan.xml | get rss.children.channel.children | get 0.item.children | get 0.link.children.0.0"
"open jonathan.xml | get rss.children.channel.children | get 0.item.children | get 3.link.children.3.0"
);
assert_eq!(

View File

@ -715,31 +715,33 @@ impl Value {
}
Value::List { vals, span } => {
let mut output = vec![];
let mut hasvalue = false;
let mut temp: Result<Value, ShellError> = Err(ShellError::NotFound(*span));
let vals = vals.iter().filter(|v| matches!(v, Value::Record { .. }));
let mut found_at_least_1_value = false;
for val in vals {
temp = val.clone().follow_cell_path(
&[PathMember::String {
val: column_name.clone(),
span: *origin_span,
}],
insensitive,
);
if let Ok(result) = temp.clone() {
hasvalue = true;
output.push(result);
// only look in records; this avoids unintentionally recursing into deeply nested tables
if matches!(val, Value::Record { .. }) {
if let Ok(result) = val.clone().follow_cell_path(
&[PathMember::String {
val: column_name.clone(),
span: *origin_span,
}],
insensitive,
) {
found_at_least_1_value = true;
output.push(result);
} else {
output.push(Value::Nothing { span: *span });
}
} else {
output.push(Value::Nothing { span: *span });
}
}
if hasvalue {
if found_at_least_1_value {
current = Value::List {
vals: output,
span: *span,
};
} else {
return temp;
return Err(ShellError::NotFound(*span));
}
}
Value::CustomValue { val, .. } => {