Skip to content

Conversation

@gertjanal
Copy link
Contributor

@gertjanal gertjanal commented Nov 12, 2025

Description

Backstory: reason why element_at exists:
SELECT ARRAY['foo', 'bar'][10] throws array out of bounds exception
SELECT element_at(ARRAY['foo', 'bar'], 10) returns NULL, which is convenient

In many queries I use, I need the first element. However, as functions are nested, the arguments are not always very readable:
element_at(element_at(filter(persons, person -> person.age > 18), 1).addresses, 1).street

This PR introduces element_first and element_last:
element_first(element_first(filter(persons, person -> person.age > 18)).addresses).street

The element_last function can be used to return the last element.

Additional context and related issues

In Java, a List has getFirst and getLast as well: https://docs.oracle.com/en/java/javase/25/docs/api//java.base/java/util/List.html#getFirst()

Naming considerations

I considered first() and array_first(), but I think element_first() is better because it is much closer to the other function that people will use, the element_at() (also better when the client auto-suggests function names when typing element_)

Release notes

## General
* Add `array_first` and `array_last` functions

@gertjanal gertjanal force-pushed the element_first_element_last branch from 2cc7cfc to 7e0539a Compare November 13, 2025 20:11
Copy link
Member

@raunaqmorarka raunaqmorarka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm
@martint PTAL

@martint
Copy link
Member

martint commented Nov 14, 2025

Seems reasonable to add these. Let's rename the functions to array_first and array_last, though.

@ebyhr ebyhr changed the title Added array functions element_first and element_last Add array_first and array_last functions Nov 14, 2025

assertThat(assertions.function("element_first", "ARRAY[1.9, 2, 2.3]"))
.isEqualTo(decimal("0000000001.9", createDecimalType(11, 1)));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add additional test with nested array as well ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added

assertThat(assertions.function("array_first", "ARRAY_FIRST(ARRAY[ARRAY[1, 2], ARRAY[3, 4]]) "))
    .isEqualTo(1);

I think that is what you mean

@gertjanal gertjanal force-pushed the element_first_element_last branch from 7e4201f to 126092b Compare November 17, 2025 20:12
@gertjanal gertjanal force-pushed the element_first_element_last branch from 126092b to 894253a Compare November 17, 2025 20:20
Copy link
Member

@martint martint left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of minor comments. Otherwise, it looks good. Once you apply the changes, I'll merge it. Thanks!

assertThat(assertions.function("array_first", "ARRAY[NULL, ARRAY[1, 2], ARRAY[3]]"))
.isNull(new ArrayType(INTEGER));

assertThat(assertions.function("array_first", "ARRAY_FIRST(ARRAY[ARRAY[1, 2], ARRAY[3, 4]]) "))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The convention for function names is to use lower case: array_first

assertThat(assertions.function("array_last", "ARRAY[ARRAY[1, 2], ARRAY[3], NULL]"))
.isNull(new ArrayType(INTEGER));

assertThat(assertions.function("array_last", "ARRAY_LAST(ARRAY[ARRAY[1, 2], ARRAY[3, 4]]) "))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

5 participants