hongyu guo created CALCITE-6740:
-----------------------------------
Summary: Case statements may generate too may same code
Key: CALCITE-6740
URL: https://issues.apache.org/jira/browse/CALCITE-6740
Project: Calcite
Issue Type: Bug
Components: core
Affects Versions: 1.38.0
Reporter: hongyu guo
Fix For: 1.39.0
reproduce
{code:java}
String sql = "with \"t\" as (select case "
+ "when \"store_id\" = 1 then '1' "
+ "when \"store_id\" = 2 then '2' "
+ "when \"store_id\" = 3 then '3' "
+ "when \"store_id\" = 4 then '4' "
+ "else '0' end as \"myid\" from (values (1),(2),(3),(6)) as
\"tt\"(\"store_id\"))\n"
+ "select case "
+ "when \"myid\" = '1' then '11' "
+ "when \"myid\" = '2' then '22' "
+ "when \"myid\" = '3' then '33' "
+ "when \"myid\" = '4' then '44' "
+ "else '0' end as \"res\" from \"t\"";
CalciteAssert.that()
.query(sql)
.returns("res=11\\nres=22\\nres=33\\nres=0 \\n");
{code}
generated code:
{code:java}
/* 1 */ public org.apache.calcite.linq4j.Enumerable bind(final
org.apache.calcite.DataContext root) {
/* 2 */ final org.apache.calcite.linq4j.Enumerable _inputEnumerable =
org.apache.calcite.linq4j.Linq4j.asEnumerable(new Integer[] {
/* 3 */ 1,
/* 4 */ 2,
/* 5 */ 3,
/* 6 */ 6});
/* 7 */ return new org.apache.calcite.linq4j.AbstractEnumerable(){
/* 8 */ public org.apache.calcite.linq4j.Enumerator enumerator() {
/* 9 */ return new org.apache.calcite.linq4j.Enumerator(){
/* 10 */ public final org.apache.calcite.linq4j.Enumerator
inputEnumerator = _inputEnumerable.enumerator();
/* 11 */ public void reset() {
/* 12 */ inputEnumerator.reset();
/* 13 */ }
/* 14 */
/* 15 */ public boolean moveNext() {
/* 16 */ return inputEnumerator.moveNext();
/* 17 */ }
/* 18 */
/* 19 */ public void close() {
/* 20 */ inputEnumerator.close();
/* 21 */ }
/* 22 */
/* 23 */ public Object current() {
/* 24 */ String case_when_value;
/* 25 */ String case_when_value0;
/* 26 */ final int current =
org.apache.calcite.runtime.SqlFunctions.toInt(inputEnumerator.current());
/* 27 */ if (current == 1) {
/* 28 */ case_when_value0 = "1";
/* 29 */ } else {
/* 30 */ if (current == 2) {
/* 31 */ case_when_value0 = "2";
/* 32 */ } else {
/* 33 */ if (current == 3) {
/* 34 */ case_when_value0 = "3";
/* 35 */ } else {
/* 36 */ if (current == 4) {
/* 37 */ case_when_value0 = "4";
/* 38 */ } else {
/* 39 */ case_when_value0 = "0";
/* 40 */ }
/* 41 */ }
/* 42 */ }
/* 43 */ }
/* 44 */ if (case_when_value0 != null &&
org.apache.calcite.runtime.SqlFunctions.eq(case_when_value0, "1")) {
/* 45 */ case_when_value = "11";
/* 46 */ } else {
/* 47 */ String case_when_value1;
/* 48 */ if (current == 1) {
/* 49 */ case_when_value1 = "1";
/* 50 */ } else {
/* 51 */ if (current == 2) {
/* 52 */ case_when_value1 = "2";
/* 53 */ } else {
/* 54 */ if (current == 3) {
/* 55 */ case_when_value1 = "3";
/* 56 */ } else {
/* 57 */ if (current == 4) {
/* 58 */ case_when_value1 = "4";
/* 59 */ } else {
/* 60 */ case_when_value1 = "0";
/* 61 */ }
/* 62 */ }
/* 63 */ }
/* 64 */ }
/* 65 */ if (case_when_value1 != null &&
org.apache.calcite.runtime.SqlFunctions.eq(case_when_value1, "2")) {
/* 66 */ case_when_value = "22";
/* 67 */ } else {
/* 68 */ String case_when_value2;
/* 69 */ if (current == 1) {
/* 70 */ case_when_value2 = "1";
/* 71 */ } else {
/* 72 */ if (current == 2) {
/* 73 */ case_when_value2 = "2";
/* 74 */ } else {
/* 75 */ if (current == 3) {
/* 76 */ case_when_value2 = "3";
/* 77 */ } else {
/* 78 */ if (current == 4) {
/* 79 */ case_when_value2 = "4";
/* 80 */ } else {
/* 81 */ case_when_value2 = "0";
/* 82 */ }
/* 83 */ }
/* 84 */ }
/* 85 */ }
/* 86 */ if (case_when_value2 != null &&
org.apache.calcite.runtime.SqlFunctions.eq(case_when_value2, "3")) {
/* 87 */ case_when_value = "33";
/* 88 */ } else {
/* 89 */ String case_when_value3;
/* 90 */ if (current == 1) {
/* 91 */ case_when_value3 = "1";
/* 92 */ } else {
/* 93 */ if (current == 2) {
/* 94 */ case_when_value3 = "2";
/* 95 */ } else {
/* 96 */ if (current == 3) {
/* 97 */ case_when_value3 = "3";
/* 98 */ } else {
/* 99 */ if (current == 4) {
/* 100 */ case_when_value3 = "4";
/* 101 */ } else {
/* 102 */ case_when_value3 = "0";
/* 103 */ }
/* 104 */ }
/* 105 */ }
/* 106 */ }
/* 107 */ if (case_when_value3 != null &&
org.apache.calcite.runtime.SqlFunctions.eq(case_when_value3, "4")) {
/* 108 */ case_when_value = "44";
/* 109 */ } else {
/* 110 */ case_when_value = "0 ";
/* 111 */ }
/* 112 */ }
/* 113 */ }
/* 114 */ }
/* 115 */ return case_when_value;
/* 116 */ }
/* 117 */
/* 118 */ };
/* 119 */ }
/* 120 */
/* 121 */ };
/* 122 */ }
/* 123 */
/* 124 */
/* 125 */ public Class getElementType() {
/* 126 */ return java.lang.String.class;
/* 127 */ }
/* 128 */
/* 129 */
{code}
The code used to calculate the `t.myid` field has been repeated multiple times.
After my debugging, I found that in the
[RexToLixTranslator#implementRecursively|https://github.com/apache/calcite/blob/648a832e0b3abc0f1cd4887847bdef7c133cb383/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java#L1464]
method, the
[RexToLixTranslator#setBlock|https://github.com/apache/calcite/blob/648a832e0b3abc0f1cd4887847bdef7c133cb383/core/src/main/java/org/apache/calcite/adapter/enumerable/RexToLixTranslator.java#L1129]
method was called to create a new translator, but the new translator did not
copy the result cache *rexResultMap* in the original translator.
--
This message was sent by Atlassian Jira
(v8.20.10#820010)