I am seeing a regression in Calcite 1.41.0 on a SQL UPDATE call that worked in 
Calcite 1.40.0. For example, using the TPC-DS schema, the following query:

    UPDATE customer SET c_first_name = 'Alice' WHERE c_customer_sk = 'some_key'

fails with:

    java.lang.AssertionError: Unexpected select list size. Select list should 
contain both target table columns and set expressions
          at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertUpdate(SqlToRelConverter.java:4472)
          at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertQueryRecursive(SqlToRelConverter.java:3997)
          at 
org.apache.calcite.sql2rel.SqlToRelConverter.convertQuery(SqlToRelConverter.java:631)

It is failing on this check, introduced in commit 
95350ed1a449bbb2f008fcf2b704544e7d95c410:

https://github.com/apache/calcite/blob/42ff295d6e28672a2ad81b1c30abfbdf44544212/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java#L4469-L4475

If I take the current state of the Calcite main branch (which also exhibits the 
same failure) and revert commit 95350ed1a449bbb2f008fcf2b704544e7d95c410, the 
resulting code allows the SQL UPDATE above to run successfully.

Looking in the debugger t the failing case, the SqlNode passed into 
SqlRelConverter.convertQuery() (with needsValidation=true, top=true) contains:

    UPDATE `CUSTOMER` SET `C_FIRST_NAME` = 'Alice'
    WHERE `C_CUSTOMER_SK` = 'some_key'

The sourceSelect for the SqlNode is null. Once execution passes the line:

    query = validator().validate(query);

The SqlNode (query) has a sourceSelect of:

    SELECT *, CAST('Alice' AS CHAR(16) CHARACTER SET `ISO-8859-1`) AS `EXPR$0`
    FROM `CUSTOMER`
    WHERE `CUSTOMER`.`C_CUSTOMER_SK` = CAST('some_key' AS BIGINT)

This means that its selectList has size 2. When it reaches the check linked 
above, this size is expected to equal the sum of the targetTable rowType 
fieldCount (18) and call sourceExpressionList size (1). 2 != 19 so the 
assertion fails.

Should I open a new Jira and add this information?

Perhaps there is a different way I can be driving the SQL-to-Rel conversion 
that avoids the problem? I notice some UPDATE unit tests included with the 
commit that introduces the problem pass. A (very) quick glance at these cases 
suggests that the query hitting the assertion has been expanded so that the 
SELECT includes all the target column names rather than '*', allowing the 
assertion check to pass. I don't know why.

Reply via email to