Skip to content

Conversation

gertjanal
Copy link
Contributor

@gertjanal gertjanal commented Sep 18, 2025

Description

Updating an item in an array is possible with the function transform(ARRAY[5, 6], x -> x + 1). This PR adds a new function to update the value for a field in a row. It can be useful when updating multiple rows in an array with a single expression, or when updating an inner value of a nested row:

For a single row:

SELECT transform(
    CAST(ROW('hello', 'world') AS ROW(greeting varchar, planet varchar))",
    'greeting', '', greeting -> concat(greeting, ' or goodbye'));
-- ROW('hello or goodbye', 'world')

For a nested row:

SELECT transform(
    CAST(ROW(ROW('hello'), 'world') as ROW(greeting ROW(text varchar), planet varchar)),
    'greeting',
    CAST(ROW('') as ROW(text varchar)),
    greeting -> transform(
        greeting, 'text', '', text -> concat(text, ' or goodbye')));
-- ROW(ROW('hello or goodbye'), 'world')
SELECT transform(ARRAY[
    cast(ROW('hello', 'world') AS ROW(greeting varchar, planet varchar)),
    cast(ROW('hi', 'mars') AS ROW(greeting varchar, planet varchar))],
    data -> transform(data, 'greeting', '', greeting -> concat(greeting, ' or goodbye')));
-- ARRAY[ROW('hello or goodbye', 'world'), ROW('hi or goodbye', 'mars')]

Additional context and related issues

This PR is a draft as I'd like the opinion of developers:

  • Is this a function we want?
  • Can the V dummy value be removed and be inferred? I couldn't get it to work without the dummy value; only .argumentType(functionType(UNKNOWN.getTypeSignature(), new TypeSignature("V"))) seemed to match the signature, but I couldn't get UNKNOWN to be updated to the actual value type.
  • Is the reading magic with the rawIndex correct? Would it still work for larger data structures?

Release notes

( ) This is not user-visible or is docs only, and no release notes are required.
( x ) Release notes are required. Please propose a release note for me.
( ) Release notes are required, with the following suggested text:

## Functions
* Add sql scalar function to transform value in a row with a single expression

@cla-bot cla-bot bot added the cla-signed label Sep 18, 2025
@github-actions github-actions bot added the docs label Sep 18, 2025
@gertjanal gertjanal force-pushed the row-transform-function branch from c3e45a5 to d4b50df Compare September 18, 2025 21:25
Block[] blocks = new Block[fields.size()];
for (int i = 0; i < fields.size(); i++) {
if (i != fieldIndex) {
blocks[i] = sqlRow.getRawFieldBlock(i).getSingleValueBlock(sqlRow.getRawIndex());
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This seems to give the right result, but is it correct to get the blocks this way?

return operatorDeclaration;
}

public static ArrayType arrayType(Type elementType)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added to be consistent with RowType.rowType

@dain dain requested a review from martint September 18, 2025 21:52
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.

2 participants