[ 
https://issues.apache.org/jira/browse/CALCITE-6740?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

hongyu guo updated CALCITE-6740:
--------------------------------
    Summary: Case statements may generate too many same code  (was: Case 
statements may generate too may same code)

> Case statements may generate too many 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
>            Priority: Major
>             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)

Reply via email to