diff --git a/coral-hive/src/main/java/com/linkedin/coral/transformers/ShiftArrayIndexTransformer.java b/coral-hive/src/main/java/com/linkedin/coral/transformers/ShiftArrayIndexTransformer.java index 95dda62f2..793210186 100644 --- a/coral-hive/src/main/java/com/linkedin/coral/transformers/ShiftArrayIndexTransformer.java +++ b/coral-hive/src/main/java/com/linkedin/coral/transformers/ShiftArrayIndexTransformer.java @@ -1,5 +1,5 @@ /** - * Copyright 2022-2023 LinkedIn Corporation. All rights reserved. + * Copyright 2022-2024 LinkedIn Corporation. All rights reserved. * Licensed under the BSD-2 Clause license. * See LICENSE in the project root for license information. */ @@ -42,16 +42,19 @@ public boolean condition(SqlCall sqlCall) { @Override public SqlCall transform(SqlCall sqlCall) { final SqlNode itemNode = sqlCall.getOperandList().get(1); + SqlNode newIndex; if (itemNode instanceof SqlNumericLiteral && deriveRelDatatype(itemNode).getSqlTypeName().equals(SqlTypeName.INTEGER)) { final Integer value = ((SqlNumericLiteral) itemNode).getValueAs(Integer.class); - sqlCall.setOperand(1, - SqlNumericLiteral.createExactNumeric(new BigDecimal(value + 1).toString(), itemNode.getParserPosition())); + newIndex = + SqlNumericLiteral.createExactNumeric(new BigDecimal(value + 1).toString(), itemNode.getParserPosition()); } else { - final SqlCall oneBasedIndex = SqlStdOperatorTable.PLUS.createCall(itemNode.getParserPosition(), itemNode, + newIndex = SqlStdOperatorTable.PLUS.createCall(itemNode.getParserPosition(), itemNode, SqlNumericLiteral.createExactNumeric("1", SqlParserPos.ZERO)); - sqlCall.setOperand(1, oneBasedIndex); } - return sqlCall; + // Create new object instead of modifying the old SqlCall to avoid transforming the same object + // multiple times if it appears multiple times in SqlNode + // TODO: Add unit test to verify the necessity of creating a new object + return SqlStdOperatorTable.ITEM.createCall(SqlParserPos.ZERO, sqlCall.getOperandList().get(0), newIndex); } }