You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by bu...@apache.org on 2016/07/26 21:23:22 UTC

[2/4] asterixdb git commit: Support CASE expression in SQL++.

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm
new file mode 100644
index 0000000..19765bd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/misc/query-ASTERIXDB-819/query-ASTERIXDB-819.1.adm
@@ -0,0 +1 @@
+null

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
index 79a9c5c..38de473 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/null-missing/is/is.1.adm
@@ -1 +1 @@
-{ "1": true, "2": false, "3": false, "4": false, "5": true, "6": true, "7": false, "8": true, "9": false, "10": true, "11": false, "12": true, "13": true, "14": true, "15": false, "16": false, "17": false, "18": true }
+{ "1": true, "3": false, "4": false, "6": true, "7": false, "8": true, "9": false, "10": true, "11": false, "12": true, "13": true, "14": true, "15": false, "16": false, "17": false, "18": true }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
index 2223305..f16c720 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/misc/ifthenelse_01/ifthenelse_01.3.ast
@@ -1,16 +1,16 @@
 DataverseUse test
 Query:
 SELECT ELEMENT [
-IfExpr [
-  Condition:
-    OperatorExpr [
+CASE    OperatorExpr [
       LiteralExpr [LONG] [2]
       >
       LiteralExpr [LONG] [1]
     ]
-  Then:
-    LiteralExpr [LONG] [20]
-  Else:
-    LiteralExpr [LONG] [10]
-]
+
+WHEN     LiteralExpr [TRUE]
+THEN     LiteralExpr [LONG] [20]
+
+ELSE     LiteralExpr [LONG] [10]
+
+END
 ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
index 279175b..1292f1a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q08_national_market_share/q08_national_market_share.3.ast
@@ -14,23 +14,24 @@ RecordConstructor [
       FunctionCall tpch.sum@1[
         (
           SELECT ELEMENT [
-          FunctionCall tpch.switch-case@5[
-            OperatorExpr [
-              FieldAccessor [
+          CASE              LiteralExpr [TRUE]
+
+          WHEN               OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=s_name
+                ]
+                =
+                LiteralExpr [STRING] [BRAZIL]
+              ]
+          THEN               FieldAccessor [
                 Variable [ Name=$i ]
-                Field=s_name
+                Field=revenue
               ]
-              =
-              LiteralExpr [STRING] [BRAZIL]
-            ]
-            LiteralExpr [TRUE]
-            FieldAccessor [
-              Variable [ Name=$i ]
-              Field=revenue
-            ]
-            LiteralExpr [FALSE]
-            LiteralExpr [DOUBLE] [0.0]
-          ]
+
+          ELSE               LiteralExpr [DOUBLE] [0.0]
+
+          END
           ]
           FROM [            Variable [ Name=$t ]
             AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
index b1fee8a..3da470a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q12_shipping/q12_shipping.3.ast
@@ -13,31 +13,35 @@ RecordConstructor [
     FunctionCall tpch.sum@1[
       (
         SELECT ELEMENT [
-        FunctionCall tpch.switch-case@5[
-          OperatorExpr [
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+        CASE            OperatorExpr [
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [1-URGENT]
               ]
-              =
-              LiteralExpr [STRING] [1-URGENT]
-            ]
-            or
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+              or
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [2-HIGH]
               ]
-              =
-              LiteralExpr [STRING] [2-HIGH]
             ]
-          ]
-          LiteralExpr [TRUE]
-          LiteralExpr [LONG] [1]
-          LiteralExpr [FALSE]
-          LiteralExpr [LONG] [0]
-        ]
+
+        WHEN             LiteralExpr [TRUE]
+        THEN             LiteralExpr [LONG] [1]
+
+        WHEN             LiteralExpr [FALSE]
+        THEN             LiteralExpr [LONG] [0]
+
+        ELSE             LiteralExpr [NULL]
+
+        END
         ]
         FROM [          Variable [ Name=$o ]
           AS Variable [ Name=$i ]
@@ -51,31 +55,35 @@ RecordConstructor [
     FunctionCall tpch.sum@1[
       (
         SELECT ELEMENT [
-        FunctionCall tpch.switch-case@5[
-          OperatorExpr [
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+        CASE            OperatorExpr [
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [1-URGENT]
               ]
-              =
-              LiteralExpr [STRING] [1-URGENT]
-            ]
-            or
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+              or
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [2-HIGH]
               ]
-              =
-              LiteralExpr [STRING] [2-HIGH]
             ]
-          ]
-          LiteralExpr [TRUE]
-          LiteralExpr [LONG] [0]
-          LiteralExpr [FALSE]
-          LiteralExpr [LONG] [1]
-        ]
+
+        WHEN             LiteralExpr [TRUE]
+        THEN             LiteralExpr [LONG] [0]
+
+        WHEN             LiteralExpr [FALSE]
+        THEN             LiteralExpr [LONG] [1]
+
+        ELSE             LiteralExpr [NULL]
+
+        END
         ]
         FROM [          Variable [ Name=$o ]
           AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
index f9f5c62..1bd404d 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch-sql-like/q14_promotion_effect/q14_promotion_effect.3.ast
@@ -7,34 +7,38 @@ OperatorExpr [
   FunctionCall tpch.sum@1[
     (
       SELECT ELEMENT [
-      FunctionCall tpch.switch-case@5[
-        OperatorExpr [
-          FieldAccessor [
-            Variable [ Name=$i ]
-            Field=p_type
-          ]
-          like
-          LiteralExpr [STRING] [PROMO%]
-        ]
-        LiteralExpr [TRUE]
-        OperatorExpr [
-          FieldAccessor [
-            Variable [ Name=$i ]
-            Field=l_extendedprice
+      CASE          OperatorExpr [
+            FieldAccessor [
+              Variable [ Name=$i ]
+              Field=p_type
+            ]
+            like
+            LiteralExpr [STRING] [PROMO%]
           ]
-          *
-          OperatorExpr [
-            LiteralExpr [LONG] [1]
-            -
+
+      WHEN           LiteralExpr [TRUE]
+      THEN           OperatorExpr [
             FieldAccessor [
               Variable [ Name=$i ]
-              Field=l_discount
+              Field=l_extendedprice
+            ]
+            *
+            OperatorExpr [
+              LiteralExpr [LONG] [1]
+              -
+              FieldAccessor [
+                Variable [ Name=$i ]
+                Field=l_discount
+              ]
             ]
           ]
-        ]
-        LiteralExpr [FALSE]
-        LiteralExpr [DOUBLE] [0.0]
-      ]
+
+      WHEN           LiteralExpr [FALSE]
+      THEN           LiteralExpr [DOUBLE] [0.0]
+
+      ELSE           LiteralExpr [NULL]
+
+      END
       ]
       FROM [        Variable [ Name=$lp ]
         AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
index 279175b..53bdb44 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q08_national_market_share/q08_national_market_share.3.ast
@@ -14,23 +14,27 @@ RecordConstructor [
       FunctionCall tpch.sum@1[
         (
           SELECT ELEMENT [
-          FunctionCall tpch.switch-case@5[
-            OperatorExpr [
-              FieldAccessor [
+          CASE              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=s_name
+                ]
+                =
+                LiteralExpr [STRING] [BRAZIL]
+              ]
+
+          WHEN               LiteralExpr [TRUE]
+          THEN               FieldAccessor [
                 Variable [ Name=$i ]
-                Field=s_name
+                Field=revenue
               ]
-              =
-              LiteralExpr [STRING] [BRAZIL]
-            ]
-            LiteralExpr [TRUE]
-            FieldAccessor [
-              Variable [ Name=$i ]
-              Field=revenue
-            ]
-            LiteralExpr [FALSE]
-            LiteralExpr [DOUBLE] [0.0]
-          ]
+
+          WHEN               LiteralExpr [FALSE]
+          THEN               LiteralExpr [DOUBLE] [0.0]
+
+          ELSE               LiteralExpr [NULL]
+
+          END
           ]
           FROM [            Variable [ Name=$t ]
             AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
index b1fee8a..6ad3a5b 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q12_shipping/q12_shipping.3.ast
@@ -13,31 +13,35 @@ RecordConstructor [
     FunctionCall tpch.sum@1[
       (
         SELECT ELEMENT [
-        FunctionCall tpch.switch-case@5[
-          OperatorExpr [
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+        CASE            OperatorExpr [
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [1-URGENT]
               ]
-              =
-              LiteralExpr [STRING] [1-URGENT]
-            ]
-            or
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+              or
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [2-HIGH]
               ]
-              =
-              LiteralExpr [STRING] [2-HIGH]
             ]
-          ]
-          LiteralExpr [TRUE]
-          LiteralExpr [LONG] [1]
-          LiteralExpr [FALSE]
-          LiteralExpr [LONG] [0]
-        ]
+
+        WHEN             LiteralExpr [TRUE]
+        THEN             LiteralExpr [LONG] [1]
+
+        WHEN             LiteralExpr [FALSE]
+        THEN             LiteralExpr [LONG] [0]
+
+        ELSE             LiteralExpr [NULL]
+
+        END
         ]
         FROM [          Variable [ Name=$o ]
           AS Variable [ Name=$i ]
@@ -51,31 +55,32 @@ RecordConstructor [
     FunctionCall tpch.sum@1[
       (
         SELECT ELEMENT [
-        FunctionCall tpch.switch-case@5[
-          OperatorExpr [
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+        CASE            LiteralExpr [TRUE]
+
+        WHEN             OperatorExpr [
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [1-URGENT]
               ]
-              =
-              LiteralExpr [STRING] [1-URGENT]
-            ]
-            or
-            OperatorExpr [
-              FieldAccessor [
-                Variable [ Name=$i ]
-                Field=o_orderpriority
+              or
+              OperatorExpr [
+                FieldAccessor [
+                  Variable [ Name=$i ]
+                  Field=o_orderpriority
+                ]
+                =
+                LiteralExpr [STRING] [2-HIGH]
               ]
-              =
-              LiteralExpr [STRING] [2-HIGH]
             ]
-          ]
-          LiteralExpr [TRUE]
-          LiteralExpr [LONG] [0]
-          LiteralExpr [FALSE]
-          LiteralExpr [LONG] [1]
-        ]
+        THEN             LiteralExpr [LONG] [0]
+
+        ELSE             LiteralExpr [LONG] [1]
+
+        END
         ]
         FROM [          Variable [ Name=$o ]
           AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
index f9f5c62..f619293 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/tpch/q14_promotion_effect/q14_promotion_effect.3.ast
@@ -7,34 +7,35 @@ OperatorExpr [
   FunctionCall tpch.sum@1[
     (
       SELECT ELEMENT [
-      FunctionCall tpch.switch-case@5[
-        OperatorExpr [
-          FieldAccessor [
-            Variable [ Name=$i ]
-            Field=p_type
-          ]
-          like
-          LiteralExpr [STRING] [PROMO%]
-        ]
-        LiteralExpr [TRUE]
-        OperatorExpr [
-          FieldAccessor [
-            Variable [ Name=$i ]
-            Field=l_extendedprice
+      CASE          OperatorExpr [
+            FieldAccessor [
+              Variable [ Name=$i ]
+              Field=p_type
+            ]
+            like
+            LiteralExpr [STRING] [PROMO%]
           ]
-          *
-          OperatorExpr [
-            LiteralExpr [LONG] [1]
-            -
+
+      WHEN           LiteralExpr [TRUE]
+      THEN           OperatorExpr [
             FieldAccessor [
               Variable [ Name=$i ]
-              Field=l_discount
+              Field=l_extendedprice
+            ]
+            *
+            OperatorExpr [
+              LiteralExpr [LONG] [1]
+              -
+              FieldAccessor [
+                Variable [ Name=$i ]
+                Field=l_discount
+              ]
             ]
           ]
-        ]
-        LiteralExpr [FALSE]
-        LiteralExpr [DOUBLE] [0.0]
-      ]
+
+      ELSE           LiteralExpr [DOUBLE] [0.0]
+
+      END
       ]
       FROM [        Variable [ Name=$lp ]
         AS Variable [ Name=$i ]

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
index 30e99e6..279522a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite.xml
@@ -3166,6 +3166,11 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="misc">
+      <compilation-unit name="ifthenelse_02">
+        <output-dir compare="Text">ifthenelse_02</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
       <compilation-unit name="is-null_01">
         <output-dir compare="Text">is-null_01</output-dir>
       </compilation-unit>
@@ -3224,6 +3229,16 @@
         <output-dir compare="Text">query-ASTERIXDB-1203</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="query-ASTERIXDB-819">
+        <output-dir compare="Text">query-ASTERIXDB-819</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="query-ASTERIXDB-819-2">
+        <output-dir compare="Text">query-ASTERIXDB-819-2</output-dir>
+      </compilation-unit>
+    </test-case>
   </test-group>
   <test-group name="open-index-enforced">
     <test-group name="open-index-enforced/error-checking">

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index e1d728d..748d924 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -2862,6 +2862,41 @@
   </test-group>
   <test-group name="misc">
     <test-case FilePath="misc">
+      <compilation-unit name="case_01">
+        <output-dir compare="Text">case_01</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_02">
+        <output-dir compare="Text">case_02</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_03">
+        <output-dir compare="Text">case_03</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_04">
+        <output-dir compare="Text">case_04</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_05">
+        <output-dir compare="Text">case_05</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_06">
+        <output-dir compare="Text">case_06</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
+      <compilation-unit name="case_07">
+        <output-dir compare="Text">case_05</output-dir>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="misc">
       <compilation-unit name="partition-by-nonexistent-field">
         <output-dir compare="Text">partition-by-nonexistent-field</output-dir>
         <expected-error>java.lang.NullPointerException</expected-error>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
index dd1a1fb..e0579f3 100644
--- a/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-aql/src/main/java/org/apache/asterix/lang/aql/visitor/AQLInlineUdfsVisitor.java
@@ -68,14 +68,14 @@ public class AQLInlineUdfsVisitor extends AbstractInlineUdfsVisitor
 
     @Override
     public Boolean visit(UnionExpr u, List<FunctionDecl> fds) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(u.getExprs(), fds);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(u.getExprs(), fds);
         u.setExprs(p.second);
         return p.first;
     }
 
     @Override
     public Boolean visit(DistinctClause dc, List<FunctionDecl> arg) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(dc.getDistinctByExpr(), arg);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(dc.getDistinctByExpr(), arg);
         dc.setDistinctByExpr(p.second);
         return p.first;
     }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
index 6b77fc7..b1df329 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Expression.java
@@ -39,7 +39,8 @@ public interface Expression extends ILangExpression {
         SELECT_EXPRESSION,
         PRIMARY_EXPRESSION,
         VALUE_EXPRESSION,
-        INDEPENDENT_SUBQUERY
+        INDEPENDENT_SUBQUERY,
+        CASE_EXPRESSION
     }
 
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
index e76436a..159af9f 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/AbstractInlineUdfsVisitor.java
@@ -103,7 +103,7 @@ public abstract class AbstractInlineUdfsVisitor extends AbstractQueryExpressionV
 
     @Override
     public Boolean visit(ListConstructor lc, List<FunctionDecl> arg) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(lc.getExprList(), arg);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(lc.getExprList(), arg);
         lc.setExprList(p.second);
         return p.first;
     }
@@ -114,24 +114,24 @@ public abstract class AbstractInlineUdfsVisitor extends AbstractQueryExpressionV
         for (FieldBinding b : rc.getFbList()) {
             Pair<Boolean, Expression> leftExprInlined = inlineUdfsInExpr(b.getLeftExpr(), arg);
             b.setLeftExpr(leftExprInlined.second);
-            changed = changed | leftExprInlined.first;
+            changed = changed || leftExprInlined.first;
             Pair<Boolean, Expression> rightExprInlined = inlineUdfsInExpr(b.getRightExpr(), arg);
             b.setRightExpr(rightExprInlined.second);
-            changed = changed | rightExprInlined.first;
+            changed = changed || rightExprInlined.first;
         }
         return changed;
     }
 
     @Override
     public Boolean visit(CallExpr pf, List<FunctionDecl> arg) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(pf.getExprList(), arg);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(pf.getExprList(), arg);
         pf.setExprList(p.second);
         return p.first;
     }
 
     @Override
     public Boolean visit(OperatorExpr ifbo, List<FunctionDecl> arg) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(ifbo.getExprList(), arg);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(ifbo.getExprList(), arg);
         ifbo.setExprList(p.second);
         return p.first;
     }
@@ -192,7 +192,7 @@ public abstract class AbstractInlineUdfsVisitor extends AbstractQueryExpressionV
 
     @Override
     public Boolean visit(OrderbyClause oc, List<FunctionDecl> arg) throws AsterixException {
-        Pair<Boolean, ArrayList<Expression>> p = inlineUdfsInExprList(oc.getOrderbyList(), arg);
+        Pair<Boolean, List<Expression>> p = inlineUdfsInExprList(oc.getOrderbyList(), arg);
         oc.setOrderbyList(p.second);
         return p.first;
     }
@@ -249,53 +249,52 @@ public abstract class AbstractInlineUdfsVisitor extends AbstractQueryExpressionV
             throws AsterixException {
         if (expr.getKind() != Kind.CALL_EXPRESSION) {
             boolean r = expr.accept(this, arg);
-            return new Pair<Boolean, Expression>(r, expr);
+            return new Pair<>(r, expr);
+        }
+        CallExpr f = (CallExpr) expr;
+        boolean r = expr.accept(this, arg);
+        FunctionDecl implem = findFuncDeclaration(f.getFunctionSignature(), arg);
+        if (implem == null) {
+            return new Pair<>(r, expr);
         } else {
-            CallExpr f = (CallExpr) expr;
-            boolean r = expr.accept(this, arg);
-            FunctionDecl implem = findFuncDeclaration(f.getFunctionSignature(), arg);
-            if (implem == null) {
-                return new Pair<Boolean, Expression>(r, expr);
-            } else {
-                // Rewrite the function body itself (without setting unbounded variables to dataset access).
-                // TODO(buyingyi): throw an exception for recursive function definition or limit the stack depth.
-                implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
-                // it's one of the functions we want to inline
-                List<LetClause> clauses = new ArrayList<LetClause>();
-                Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
-                VariableSubstitutionEnvironment subts = new VariableSubstitutionEnvironment();
-                for (Expression e : f.getExprList()) {
-                    VarIdentifier param = paramIter.next();
-                    // Obs: we could do smth about passing also literals, or let
-                    // variable inlining to take care of this.
-                    if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
-                        subts.addSubstituion(new VariableExpr(param), e);
-                    } else {
-                        VarIdentifier newV = context.newVariable();
-                        Pair<ILangExpression, VariableSubstitutionEnvironment> p1 = e.accept(cloneVisitor,
-                                new VariableSubstitutionEnvironment());
-                        LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
-                        clauses.add(c);
-                        subts.addSubstituion(new VariableExpr(param), new VariableExpr(newV));
-                    }
-                }
-
-                Pair<ILangExpression, VariableSubstitutionEnvironment> p2 = implem.getFuncBody().accept(cloneVisitor,
-                        subts);
-                Expression resExpr;
-                if (clauses.isEmpty()) {
-                    resExpr = (Expression) p2.first;
+            // Rewrite the function body itself (without setting unbounded variables to dataset access).
+            // TODO(buyingyi): throw an exception for recursive function definition or limit the stack depth.
+            implem.setFuncBody(rewriteFunctionBody(implem.getFuncBody()));
+            // it's one of the functions we want to inline
+            List<LetClause> clauses = new ArrayList<>();
+            Iterator<VarIdentifier> paramIter = implem.getParamList().iterator();
+            VariableSubstitutionEnvironment subts = new VariableSubstitutionEnvironment();
+            for (Expression e : f.getExprList()) {
+                VarIdentifier param = paramIter.next();
+                // Obs: we could do smth about passing also literals, or let
+                // variable inlining to take care of this.
+                if (e.getKind() == Kind.VARIABLE_EXPRESSION) {
+                    subts.addSubstituion(new VariableExpr(param), e);
                 } else {
-                    resExpr = generateQueryExpression(clauses, (Expression) p2.first);
+                    VarIdentifier newV = context.newVariable();
+                    Pair<ILangExpression, VariableSubstitutionEnvironment> p1 =
+                            e.accept(cloneVisitor, new VariableSubstitutionEnvironment());
+                    LetClause c = new LetClause(new VariableExpr(newV), (Expression) p1.first);
+                    clauses.add(c);
+                    subts.addSubstituion(new VariableExpr(param), new VariableExpr(newV));
                 }
-                return new Pair<Boolean, Expression>(true, resExpr);
             }
+
+            Pair<ILangExpression, VariableSubstitutionEnvironment> p2 =
+                    implem.getFuncBody().accept(cloneVisitor, subts);
+            Expression resExpr;
+            if (clauses.isEmpty()) {
+                resExpr = (Expression) p2.first;
+            } else {
+                resExpr = generateQueryExpression(clauses, (Expression) p2.first);
+            }
+            return new Pair<>(true, resExpr);
         }
     }
 
-    protected Pair<Boolean, ArrayList<Expression>> inlineUdfsInExprList(List<Expression> exprList,
-            List<FunctionDecl> fds) throws AsterixException {
-        ArrayList<Expression> newList = new ArrayList<Expression>();
+    protected Pair<Boolean, List<Expression>> inlineUdfsInExprList(List<Expression> exprList, List<FunctionDecl> fds)
+            throws AsterixException {
+        ArrayList<Expression> newList = new ArrayList<>();
         boolean changed = false;
         for (Expression e : exprList) {
             Pair<Boolean, Expression> p = inlineUdfsInExpr(e, fds);
@@ -304,7 +303,7 @@ public abstract class AbstractInlineUdfsVisitor extends AbstractQueryExpressionV
                 changed = true;
             }
         }
-        return new Pair<Boolean, ArrayList<Expression>>(changed, newList);
+        return new Pair<>(changed, newList);
     }
 
     protected Expression rewriteFunctionBody(Expression expr) throws AsterixException {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
index 1fd561e..073e413 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/SubstituteExpressionVisitor.java
@@ -48,7 +48,7 @@ import org.apache.asterix.lang.common.visitor.base.AbstractQueryExpressionVisito
 
 public abstract class SubstituteExpressionVisitor
         extends AbstractQueryExpressionVisitor<Expression, ExpressionSubstitutionEnvironment> {
-    private final DeepCopier deepCopier;
+    protected final DeepCopier deepCopier;
 
     public SubstituteExpressionVisitor(DeepCopier deepCopier) {
         this.deepCopier = deepCopier;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java
new file mode 100644
index 0000000..45ff082
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/expression/CaseExpression.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.expression;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.literal.NullLiteral;
+import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.base.ISqlppVisitor;
+import org.apache.commons.lang3.ObjectUtils;
+
+public class CaseExpression implements Expression {
+
+    private Expression conditionExpr;
+    private List<Expression> whenExprs = new ArrayList<>();
+    private List<Expression> thenExprs = new ArrayList<>();
+    private Expression elseExpr; // elseExpr could be null.
+
+    public CaseExpression(Expression conditionExpr, List<Expression> whenExprs, List<Expression> thenExprs,
+            Expression elseExpr) {
+        this.conditionExpr = conditionExpr;
+        this.whenExprs.addAll(whenExprs);
+        this.thenExprs.addAll(thenExprs);
+
+        // If no when expression matches the case expr, we return null
+        this.elseExpr = elseExpr == null ? new LiteralExpr(NullLiteral.INSTANCE) : elseExpr;
+    }
+
+    @Override
+    public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws AsterixException {
+        return ((ISqlppVisitor<R, T>) visitor).visit(this, arg);
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CASE_EXPRESSION;
+    }
+
+    public Expression getConditionExpr() {
+        return conditionExpr;
+    }
+
+    public Expression getElseExpr() {
+        return elseExpr;
+    }
+
+    public List<Expression> getWhenExprs() {
+        return whenExprs;
+    }
+
+    public List<Expression> getThenExprs() {
+        return thenExprs;
+    }
+
+    public void setConditionExpr(Expression conditionExpr) {
+        this.conditionExpr = conditionExpr;
+    }
+
+    public void setElseExpr(Expression elseExpr) {
+        this.elseExpr = elseExpr;
+    }
+
+    public void setWhenExprs(List<Expression> whenExprs) {
+        this.whenExprs = whenExprs;
+    }
+
+    public void setThenExprs(List<Expression> thenExprs) {
+        this.thenExprs = thenExprs;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("CASE ");
+        sb.append(conditionExpr);
+        sb.append("\n");
+        for (int index = 0; index < whenExprs.size(); ++index) {
+            sb.append("WHEN ");
+            sb.append(whenExprs.get(index));
+            sb.append(" THEN ");
+            sb.append(thenExprs.get(index));
+            sb.append("\n");
+        }
+        sb.append("ELSE ");
+        sb.append(elseExpr);
+        sb.append("END\n");
+        return sb.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return ObjectUtils.hashCodeMulti(conditionExpr, elseExpr, thenExprs, whenExprs);
+    }
+
+    @Override
+    public boolean equals(Object object) {
+        if (this == object) {
+            return true;
+        }
+        if (!(object instanceof CaseExpression)) {
+            return false;
+        }
+        CaseExpression target = (CaseExpression) object;
+        return ObjectUtils.equals(conditionExpr, target.conditionExpr) && ObjectUtils.equals(elseExpr, target.elseExpr)
+                && ObjectUtils.equals(thenExprs, target.thenExprs) && ObjectUtils.equals(thenExprs, thenExprs);
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index d0e2aa3..c85097d 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -45,6 +45,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.parser.FunctionParser;
@@ -441,5 +442,18 @@ class SqlppQueryRewriter implements IQueryRewriter {
             return null;
         }
 
+        @Override
+        public Void visit(CaseExpression caseExpression, Void arg) throws AsterixException {
+            caseExpression.getConditionExpr().accept(this, arg);
+            for (Expression expr : caseExpression.getWhenExprs()) {
+                expr.accept(this, arg);
+            }
+            for (Expression expr : caseExpression.getThenExprs()) {
+                expr.accept(this, arg);
+            }
+            caseExpression.getElseExpr().accept(this, arg);
+            return null;
+        }
+
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
index 57cbdc5..4aa25d7 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/InlineColumnAliasVisitor.java
@@ -64,6 +64,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -462,6 +463,19 @@ public class InlineColumnAliasVisitor extends AbstractSqlppQueryExpressionVisito
         return null;
     }
 
+    @Override
+    public Void visit(CaseExpression caseExpression, Boolean overwriteWithGbyKeyVarRefs) throws AsterixException {
+        caseExpression.getConditionExpr().accept(this, overwriteWithGbyKeyVarRefs);
+        for (Expression expr : caseExpression.getWhenExprs()) {
+            expr.accept(this, overwriteWithGbyKeyVarRefs);
+        }
+        for (Expression expr : caseExpression.getThenExprs()) {
+            expr.accept(this, overwriteWithGbyKeyVarRefs);
+        }
+        caseExpression.getElseExpr().accept(this, overwriteWithGbyKeyVarRefs);
+        return null;
+    }
+
     private void removeSubsutitions(AbstractBinaryCorrelateClause unnestClause) {
         scopeChecker.getCurrentScope().removeSymbolExpressionMapping(unnestClause.getRightVariable());
         if (unnestClause.hasPositionalVariable()) {

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
index e046ccf..a3346ed 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppBuiltinFunctionRewriteVisitor.java
@@ -21,13 +21,20 @@ package org.apache.asterix.lang.sqlpp.rewrites.visitor;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.apache.asterix.common.config.MetadataConstants;
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.lang.common.base.Expression;
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.OperatorExpr;
+import org.apache.asterix.lang.common.literal.TrueLiteral;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
+import org.apache.asterix.lang.sqlpp.util.SqlppRewriteUtil;
 import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppSimpleExpressionVisitor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
 
 public class SqlppBuiltinFunctionRewriteVisitor extends AbstractSqlppSimpleExpressionVisitor {
 
@@ -44,4 +51,49 @@ public class SqlppBuiltinFunctionRewriteVisitor extends AbstractSqlppSimpleExpre
         return callExpr;
     }
 
+    @Override
+    public Expression visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+        Expression expr = super.visit(caseExpr, arg); // Visits it as usual first.
+        if (expr != caseExpr) {
+            return expr.accept(this, arg);
+        }
+        CaseExpression newCaseExpr = normalizeCaseExpr(caseExpr);
+        if (SqlppRewriteUtil.constainsSubquery(newCaseExpr)) {
+            // If the CASE expression contains a subquery, we do not rewrite it to a switch-case function call.
+            return newCaseExpr;
+        }
+        // If the CASE expression does not contain a subquery, we rewrite it to a switch-case function call.
+        FunctionSignature functionSignature = new FunctionSignature(MetadataConstants.METADATA_DATAVERSE_NAME,
+                "switch-case", FunctionIdentifier.VARARGS);
+        List<Expression> whenExprList = newCaseExpr.getWhenExprs();
+        List<Expression> thenExprList = newCaseExpr.getThenExprs();
+        List<Expression> newExprList = new ArrayList<>();
+        newExprList.add(newCaseExpr.getConditionExpr());
+        for (int index = 0; index < whenExprList.size(); ++index) {
+            newExprList.add(whenExprList.get(index));
+            newExprList.add(thenExprList.get(index));
+        }
+        newExprList.add(newCaseExpr.getElseExpr());
+        return new CallExpr(functionSignature, newExprList);
+    }
+
+    // Normalizes WHEN expressions so that it can have correct NULL/MISSING semantics as well
+    // as type promotion semantics.
+    private CaseExpression normalizeCaseExpr(CaseExpression caseExpr) throws AsterixException {
+        LiteralExpr trueLiteral = new LiteralExpr(TrueLiteral.INSTANCE);
+        Expression conditionExpr = caseExpr.getConditionExpr();
+        if (trueLiteral.equals(conditionExpr)) {
+            return caseExpr;
+        }
+        List<Expression> normalizedWhenExprs = new ArrayList<>();
+        for (Expression expr : caseExpr.getWhenExprs()) {
+            OperatorExpr operatorExpr = new OperatorExpr();
+            operatorExpr.addOperand((Expression) SqlppRewriteUtil.deepCopy(expr));
+            operatorExpr.addOperand(caseExpr.getConditionExpr());
+            operatorExpr.addOperator("=");
+            normalizedWhenExprs.add(operatorExpr);
+        }
+        return new CaseExpression(trueLiteral, normalizedWhenExprs, caseExpr.getThenExprs(), caseExpr.getElseExpr());
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
index 194c029..d2730ff 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppInlineUdfsVisitor.java
@@ -43,6 +43,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -75,9 +76,7 @@ public class SqlppInlineUdfsVisitor extends AbstractInlineUdfsVisitor
     protected Expression generateQueryExpression(List<LetClause> letClauses, Expression returnExpr)
             throws AsterixException {
         Map<VariableExpr, Expression> varExprMap = extractLetBindingVariableExpressionMappings(letClauses);
-        Expression inlinedReturnExpr = (Expression) SqlppVariableSubstitutionUtil
-                .substituteVariableWithoutContext(returnExpr, varExprMap);
-        return inlinedReturnExpr;
+        return (Expression) SqlppVariableSubstitutionUtil.substituteVariableWithoutContext(returnExpr, varExprMap);
     }
 
     @Override
@@ -231,9 +230,28 @@ public class SqlppInlineUdfsVisitor extends AbstractInlineUdfsVisitor
         return p.first;
     }
 
+    @Override
+    public Boolean visit(CaseExpression caseExpr, List<FunctionDecl> funcs) throws AsterixException {
+        Pair<Boolean, Expression> result = inlineUdfsInExpr(caseExpr.getConditionExpr(), funcs);
+        caseExpr.setConditionExpr(result.second);
+        boolean inlined = result.first;
+
+        Pair<Boolean, List<Expression>> inlinedList = inlineUdfsInExprList(caseExpr.getWhenExprs(), funcs);
+        inlined = inlined || inlinedList.first;
+        caseExpr.setWhenExprs(inlinedList.second);
+
+        inlinedList = inlineUdfsInExprList(caseExpr.getThenExprs(), funcs);
+        inlined = inlined || inlinedList.first;
+        caseExpr.setThenExprs(inlinedList.second);
+
+        result = inlineUdfsInExpr(caseExpr.getElseExpr(), funcs);
+        caseExpr.setElseExpr(result.second);
+        return inlined || result.first;
+    }
+
     private Map<VariableExpr, Expression> extractLetBindingVariableExpressionMappings(List<LetClause> letClauses)
             throws AsterixException {
-        Map<VariableExpr, Expression> varExprMap = new HashMap<VariableExpr, Expression>();
+        Map<VariableExpr, Expression> varExprMap = new HashMap<>();
         for (LetClause lc : letClauses) {
             // inline let variables one by one iteratively.
             lc.setBindingExpr((Expression) SqlppVariableSubstitutionUtil

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
index 4a8c69d..9bc1813 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/util/SqlppRewriteUtil.java
@@ -28,6 +28,7 @@ import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.sqlpp.rewrites.visitor.SqlppGroupBySugarVisitor;
+import org.apache.asterix.lang.sqlpp.visitor.CheckSubqueryVisitor;
 import org.apache.asterix.lang.sqlpp.visitor.DeepCopyVisitor;
 import org.apache.asterix.lang.sqlpp.visitor.FreeVariableVisitor;
 
@@ -60,4 +61,13 @@ public class SqlppRewriteUtil {
         return expr.accept(visitor, null);
     }
 
+    // Checks if an ILangExpression contains a subquery.
+    public static boolean constainsSubquery(ILangExpression expr) throws AsterixException {
+        if (expr == null) {
+            return false;
+        }
+        CheckSubqueryVisitor visitor = new CheckSubqueryVisitor();
+        return expr.accept(visitor, null);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
index 669b0a8..ca25775 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSql92AggregateVisitor.java
@@ -55,13 +55,14 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.util.FunctionMapUtil;
 import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
 
 /**
- * This visitor checks if a language construct contains SQL-92 aggregates.
+ * This visitor checks if a non-subquery language construct contains SQL-92 aggregates.
  */
 public class CheckSql92AggregateVisitor extends AbstractSqlppQueryExpressionVisitor<Boolean, ILangExpression> {
 
@@ -271,4 +272,10 @@ public class CheckSql92AggregateVisitor extends AbstractSqlppQueryExpressionVisi
         return false;
     }
 
+    @Override
+    public Boolean visit(CaseExpression caseExpr, ILangExpression arg) throws AsterixException {
+        return caseExpr.getConditionExpr().accept(this, arg) || visitExprList(caseExpr.getWhenExprs(), arg)
+                || visitExprList(caseExpr.getThenExprs(), arg) || caseExpr.getElseExpr().accept(this, arg);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
new file mode 100644
index 0000000..e772df5
--- /dev/null
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/CheckSubqueryVisitor.java
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.lang.sqlpp.visitor;
+
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.AsterixException;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.ILangExpression;
+import org.apache.asterix.lang.common.clause.GroupbyClause;
+import org.apache.asterix.lang.common.clause.LetClause;
+import org.apache.asterix.lang.common.clause.LimitClause;
+import org.apache.asterix.lang.common.clause.OrderbyClause;
+import org.apache.asterix.lang.common.clause.WhereClause;
+import org.apache.asterix.lang.common.expression.CallExpr;
+import org.apache.asterix.lang.common.expression.FieldAccessor;
+import org.apache.asterix.lang.common.expression.FieldBinding;
+import org.apache.asterix.lang.common.expression.GbyVariableExpressionPair;
+import org.apache.asterix.lang.common.expression.IfExpr;
+import org.apache.asterix.lang.common.expression.IndexAccessor;
+import org.apache.asterix.lang.common.expression.ListConstructor;
+import org.apache.asterix.lang.common.expression.LiteralExpr;
+import org.apache.asterix.lang.common.expression.OperatorExpr;
+import org.apache.asterix.lang.common.expression.QuantifiedExpression;
+import org.apache.asterix.lang.common.expression.RecordConstructor;
+import org.apache.asterix.lang.common.expression.UnaryExpr;
+import org.apache.asterix.lang.common.expression.VariableExpr;
+import org.apache.asterix.lang.common.statement.FunctionDecl;
+import org.apache.asterix.lang.common.statement.Query;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.struct.QuantifiedPair;
+import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
+import org.apache.asterix.lang.sqlpp.clause.FromClause;
+import org.apache.asterix.lang.sqlpp.clause.FromTerm;
+import org.apache.asterix.lang.sqlpp.clause.HavingClause;
+import org.apache.asterix.lang.sqlpp.clause.JoinClause;
+import org.apache.asterix.lang.sqlpp.clause.NestClause;
+import org.apache.asterix.lang.sqlpp.clause.Projection;
+import org.apache.asterix.lang.sqlpp.clause.SelectBlock;
+import org.apache.asterix.lang.sqlpp.clause.SelectClause;
+import org.apache.asterix.lang.sqlpp.clause.SelectElement;
+import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
+import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
+import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
+import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
+import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
+import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
+import org.apache.asterix.lang.sqlpp.visitor.base.AbstractSqlppQueryExpressionVisitor;
+import org.apache.hyracks.algebricks.common.utils.Pair;
+
+/**
+ * This visitor recursively checks if there is a subquery in the argument language construct.
+ */
+public class CheckSubqueryVisitor extends AbstractSqlppQueryExpressionVisitor<Boolean, ILangExpression> {
+
+    @Override
+    public Boolean visit(FromClause fromClause, ILangExpression arg) throws AsterixException {
+        for (FromTerm fromTerm : fromClause.getFromTerms()) {
+            if (fromTerm.accept(this, arg)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public Boolean visit(FromTerm fromTerm, ILangExpression arg) throws AsterixException {
+        if (visit(fromTerm.getLeftExpression(), arg)) {
+            return true;
+        }
+        for (AbstractBinaryCorrelateClause correlateClause : fromTerm.getCorrelateClauses()) {
+            if (correlateClause.accept(this, arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean visit(JoinClause joinClause, ILangExpression arg) throws AsterixException {
+        return visit(joinClause.getRightExpression(), arg) || visit(joinClause.getConditionExpression(), arg);
+    }
+
+    @Override
+    public Boolean visit(NestClause nestClause, ILangExpression arg) throws AsterixException {
+        return nestClause.accept(this, arg);
+    }
+
+    @Override
+    public Boolean visit(Projection projection, ILangExpression arg) throws AsterixException {
+        if (projection.star()) {
+            return false;
+        }
+        return visit(projection.getExpression(), arg);
+    }
+
+    @Override
+    public Boolean visit(SelectBlock selectBlock, ILangExpression arg) throws AsterixException {
+        boolean hasSubquery = visit(selectBlock.getFromClause(), arg) || visit(selectBlock.getGroupbyClause(), arg)
+                || visit(selectBlock.getHavingClause(), arg) || visit(selectBlock.getWhereClause(), arg);
+        return hasSubquery || visit(selectBlock.getSelectClause(), arg) || visit(selectBlock.getLetList(), arg)
+                || visit(selectBlock.getLetListAfterGroupby(), arg);
+    }
+
+    @Override
+    public Boolean visit(SelectClause selectClause, ILangExpression arg) throws AsterixException {
+        return visit(selectClause.getSelectElement(), arg) || visit(selectClause.getSelectRegular(), arg);
+    }
+
+    @Override
+    public Boolean visit(SelectElement selectElement, ILangExpression arg) throws AsterixException {
+        return visit(selectElement.getExpression(), arg);
+    }
+
+    @Override
+    public Boolean visit(SelectRegular selectRegular, ILangExpression arg) throws AsterixException {
+        return visit(selectRegular.getProjections(), arg);
+    }
+
+    @Override
+    public Boolean visit(SelectSetOperation selectSetOperation, ILangExpression arg) throws AsterixException {
+        if (selectSetOperation.getLeftInput().accept(this, arg)) {
+            return true;
+        }
+        for (SetOperationRight right : selectSetOperation.getRightInputs()) {
+            if (right.getSetOperationRightInput().accept(this, arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean visit(SelectExpression selectStatement, ILangExpression arg) throws AsterixException {
+        if (selectStatement.isSubquery()) {
+            return true;
+        }
+        return visit(selectStatement.getLetList(), arg) || visit(selectStatement.getSelectSetOperation(), arg)
+                || visit(selectStatement.getOrderbyClause(), arg) || visit(selectStatement.getLimitClause(), arg);
+
+    }
+
+    @Override
+    public Boolean visit(UnnestClause unnestClause, ILangExpression arg) throws AsterixException {
+        return visit(unnestClause.getRightExpression(), arg);
+    }
+
+    @Override
+    public Boolean visit(HavingClause havingClause, ILangExpression arg) throws AsterixException {
+        return visit(havingClause.getFilterExpression(), arg);
+    }
+
+    @Override
+    public Boolean visit(IndependentSubquery independentSubquery, ILangExpression arg) throws AsterixException {
+        return visit(independentSubquery.getExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(CaseExpression caseExpression, ILangExpression arg) throws AsterixException {
+        return visit(caseExpression.getConditionExpr(), arg) || visit(caseExpression.getWhenExprs(), arg)
+                || visit(caseExpression.getThenExprs(), arg) || visit(caseExpression.getElseExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(Query q, ILangExpression arg) throws AsterixException {
+        return visit(q.getBody(), arg);
+    }
+
+    @Override
+    public Boolean visit(FunctionDecl fd, ILangExpression arg) throws AsterixException {
+        return fd.getFuncBody().accept(this, arg);
+    }
+
+    @Override
+    public Boolean visit(LiteralExpr l, ILangExpression arg) throws AsterixException {
+        return false;
+    }
+
+    @Override
+    public Boolean visit(VariableExpr v, ILangExpression arg) throws AsterixException {
+        return false;
+    }
+
+    @Override
+    public Boolean visit(ListConstructor lc, ILangExpression arg) throws AsterixException {
+        return visit(lc.getExprList(), arg);
+    }
+
+    @Override
+    public Boolean visit(RecordConstructor rc, ILangExpression arg) throws AsterixException {
+        for (FieldBinding fb : rc.getFbList()) {
+            if (visit(fb.getLeftExpr(), arg)) {
+                return true;
+            }
+            if (visit(fb.getRightExpr(), arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean visit(OperatorExpr operatorExpr, ILangExpression arg) throws AsterixException {
+        return visit(operatorExpr.getExprList(), arg);
+    }
+
+    @Override
+    public Boolean visit(FieldAccessor fa, ILangExpression arg) throws AsterixException {
+        return visit(fa.getExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(IndexAccessor ia, ILangExpression arg) throws AsterixException {
+        return visit(ia.getExpr(), arg) || visit(ia.getIndexExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(IfExpr ifexpr, ILangExpression arg) throws AsterixException {
+        return visit(ifexpr.getCondExpr(), arg) || visit(ifexpr.getThenExpr(), arg) || visit(ifexpr.getElseExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(QuantifiedExpression qe, ILangExpression arg) throws AsterixException {
+        for (QuantifiedPair qf : qe.getQuantifiedList()) {
+            if (visit(qf.getExpr(), arg)) {
+                return true;
+            }
+        }
+        return visit(qe.getSatisfiesExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(LetClause lc, ILangExpression arg) throws AsterixException {
+        return visit(lc.getBindingExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(WhereClause wc, ILangExpression arg) throws AsterixException {
+        return visit(wc.getWhereExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(OrderbyClause oc, ILangExpression arg) throws AsterixException {
+        return visit(oc.getOrderbyList(), arg);
+    }
+
+    @Override
+    public Boolean visit(GroupbyClause gc, ILangExpression arg) throws AsterixException {
+        for (GbyVariableExpressionPair key : gc.getGbyPairList()) {
+            if (visit(key.getExpr(), arg)) {
+                return true;
+            }
+        }
+        for (GbyVariableExpressionPair key : gc.getDecorPairList()) {
+            if (visit(key.getExpr(), arg)) {
+                return true;
+            }
+        }
+        for (Pair<Expression, Identifier> field : gc.getGroupFieldList()) {
+            if (visit(field.first, arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public Boolean visit(LimitClause lc, ILangExpression arg) throws AsterixException {
+        return visit(lc.getLimitExpr(), arg) || visit(lc.getOffset(), arg);
+    }
+
+    @Override
+    public Boolean visit(UnaryExpr u, ILangExpression arg) throws AsterixException {
+        return visit(u.getExpr(), arg);
+    }
+
+    @Override
+    public Boolean visit(CallExpr callExpr, ILangExpression arg) throws AsterixException {
+        return visit(callExpr.getExprList(), arg);
+    }
+
+    private boolean visit(List<?> langExprs, ILangExpression arg) throws AsterixException {
+        for (Object o : langExprs) {
+            ILangExpression langExpr = (ILangExpression) o;
+            if (langExpr.accept(this, arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean visit(ILangExpression langExpr, ILangExpression arg) throws AsterixException {
+        if (langExpr == null) {
+            return false;
+        }
+        return langExpr.accept(this, arg);
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
index bafb8c0..01f3524 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/DeepCopyVisitor.java
@@ -60,6 +60,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
@@ -334,11 +335,7 @@ public class DeepCopyVisitor extends AbstractSqlppQueryExpressionVisitor<ILangEx
 
     @Override
     public ListConstructor visit(ListConstructor lc, Void arg) throws AsterixException {
-        List<Expression> newExprList = new ArrayList<>();
-        for (Expression expr : lc.getExprList()) {
-            newExprList.add((Expression) expr.accept(this, arg));
-        }
-        return new ListConstructor(lc.getType(), newExprList);
+        return new ListConstructor(lc.getType(), copyExprList(lc.getExprList(), arg));
     }
 
     @Override
@@ -354,12 +351,8 @@ public class DeepCopyVisitor extends AbstractSqlppQueryExpressionVisitor<ILangEx
 
     @Override
     public OperatorExpr visit(OperatorExpr operatorExpr, Void arg) throws AsterixException {
-        List<Expression> newExprList = new ArrayList<>();
-        for (Expression expr : operatorExpr.getExprList()) {
-            newExprList.add((Expression) expr.accept(this, arg));
-        }
-        return new OperatorExpr(newExprList, operatorExpr.getExprBroadcastIdx(), operatorExpr.getOpList(),
-                operatorExpr.isCurrentop());
+        return new OperatorExpr(copyExprList(operatorExpr.getExprList(), arg), operatorExpr.getExprBroadcastIdx(),
+                operatorExpr.getOpList(), operatorExpr.isCurrentop());
     }
 
     @Override
@@ -415,7 +408,7 @@ public class DeepCopyVisitor extends AbstractSqlppQueryExpressionVisitor<ILangEx
         Expression expr = (Expression) ia.getExpr().accept(this, arg);
         Expression indexExpr = null;
         if (ia.getIndexExpr() != null) {
-            indexExpr = ia.getIndexExpr();
+            indexExpr = (Expression) ia.getIndexExpr().accept(this, arg);
         }
         return new IndexAccessor(expr, indexExpr);
     }
@@ -425,4 +418,21 @@ public class DeepCopyVisitor extends AbstractSqlppQueryExpressionVisitor<ILangEx
         return new IndependentSubquery((Expression) independentSubquery.getExpr().accept(this, arg));
     }
 
+    @Override
+    public ILangExpression visit(CaseExpression caseExpr, Void arg) throws AsterixException {
+        Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, arg);
+        List<Expression> whenExprList = copyExprList(caseExpr.getWhenExprs(), arg);
+        List<Expression> thenExprList = copyExprList(caseExpr.getThenExprs(), arg);
+        Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, arg);
+        return new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
+    }
+
+    private List<Expression> copyExprList(List<Expression> exprs, Void arg) throws AsterixException {
+        List<Expression> newExprList = new ArrayList<>();
+        for (Expression expr : exprs) {
+            newExprList.add((Expression) expr.accept(this, arg));
+        }
+        return newExprList;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
index 37c19ab..20b144c 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/FreeVariableVisitor.java
@@ -60,6 +60,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -159,8 +160,8 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
         Collection<VariableExpr> fromBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getFromClause());
         Collection<VariableExpr> letsBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getLetList());
         Collection<VariableExpr> gbyBindingVars = SqlppVariableUtil.getBindingVariables(selectBlock.getGroupbyClause());
-        Collection<VariableExpr> gbyLetsBindingVars = SqlppVariableUtil
-                .getBindingVariables(selectBlock.getLetListAfterGroupby());
+        Collection<VariableExpr> gbyLetsBindingVars =
+                SqlppVariableUtil.getBindingVariables(selectBlock.getLetListAfterGroupby());
 
         selectBlock.getSelectClause().accept(this, selectFreeVars);
         // Removes group-by, from, let, and gby-let binding vars.
@@ -270,9 +271,7 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
 
     @Override
     public Void visit(OrderbyClause oc, Collection<VariableExpr> freeVars) throws AsterixException {
-        for (Expression orderExpr : oc.getOrderbyList()) {
-            orderExpr.accept(this, freeVars);
-        }
+        visit(oc.getOrderbyList(), freeVars);
         return null;
     }
 
@@ -340,9 +339,7 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
 
     @Override
     public Void visit(ListConstructor lc, Collection<VariableExpr> freeVars) throws AsterixException {
-        for (Expression expr : lc.getExprList()) {
-            expr.accept(this, freeVars);
-        }
+        visit(lc.getExprList(), freeVars);
         return null;
     }
 
@@ -357,9 +354,7 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
 
     @Override
     public Void visit(OperatorExpr operatorExpr, Collection<VariableExpr> freeVars) throws AsterixException {
-        for (Expression expr : operatorExpr.getExprList()) {
-            expr.accept(this, freeVars);
-        }
+        visit(operatorExpr.getExprList(), freeVars);
         return null;
     }
 
@@ -416,8 +411,18 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
     }
 
     @Override
-    public Void visit(IndependentSubquery independentSubquery, Collection<VariableExpr> arg) throws AsterixException {
-        independentSubquery.getExpr().accept(this, arg);
+    public Void visit(IndependentSubquery independentSubquery, Collection<VariableExpr> freeVars)
+            throws AsterixException {
+        independentSubquery.getExpr().accept(this, freeVars);
+        return null;
+    }
+
+    @Override
+    public Void visit(CaseExpression caseExpr, Collection<VariableExpr> freeVars) throws AsterixException {
+        caseExpr.getConditionExpr().accept(this, freeVars);
+        visit(caseExpr.getWhenExprs(), freeVars);
+        visit(caseExpr.getThenExprs(), freeVars);
+        caseExpr.getElseExpr().accept(this, freeVars);
         return null;
     }
 
@@ -454,6 +459,12 @@ public class FreeVariableVisitor extends AbstractSqlppQueryExpressionVisitor<Voi
         freeVars.addAll(conditionFreeVars);
     }
 
+    private void visit(List<Expression> exprs, Collection<VariableExpr> arg) throws AsterixException {
+        for (Expression expr : exprs) {
+            expr.accept(this, arg);
+        }
+    }
+
     /**
      * Removes all binding variables defined in the select block for a free variable collection.
      *

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
index 589381a..4413961 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppAstPrintVisitor.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.lang.sqlpp.visitor;
 
 import java.io.PrintWriter;
+import java.util.List;
 
 import org.apache.asterix.common.exceptions.AsterixException;
 import org.apache.asterix.common.functions.FunctionSignature;
@@ -42,6 +43,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -250,8 +252,8 @@ public class SqlppAstPrintVisitor extends QueryPrintVisitor implements ISqlppVis
     @Override
     public Void visit(CallExpr pf, Integer step) throws AsterixException {
         FunctionSignature functionSignature = pf.getFunctionSignature();
-        FunctionSignature normalizedFunctionSignature = FunctionMapUtil
-                .normalizeBuiltinFunctionSignature(functionSignature, false);
+        FunctionSignature normalizedFunctionSignature =
+                FunctionMapUtil.normalizeBuiltinFunctionSignature(functionSignature, false);
         if (AsterixBuiltinFunctions.isBuiltinCompilerFunction(normalizedFunctionSignature, true)) {
             functionSignature = normalizedFunctionSignature;
         }
@@ -299,4 +301,25 @@ public class SqlppAstPrintVisitor extends QueryPrintVisitor implements ISqlppVis
         return null;
     }
 
+    @Override
+    public Void visit(CaseExpression caseExpr, Integer step) throws AsterixException {
+        out.print(skip(step) + "CASE");
+        caseExpr.getConditionExpr().accept(this, step + 2);
+        out.println();
+        List<Expression> whenExprs = caseExpr.getWhenExprs();
+        List<Expression> thenExprs = caseExpr.getThenExprs();
+        for (int index = 0; index < whenExprs.size(); ++index) {
+            out.print(skip(step) + "WHEN ");
+            whenExprs.get(index).accept(this, step + 2);
+            out.print(skip(step) + "THEN ");
+            thenExprs.get(index).accept(this, step + 2);
+            out.println();
+        }
+        out.print(skip(step) + "ELSE ");
+        caseExpr.getElseExpr().accept(this, step + 2);
+        out.println();
+        out.println(skip(step) + "END");
+        return null;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
index d380cad..23181e4 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppCloneAndSubstituteVariablesVisitor.java
@@ -33,6 +33,7 @@ import org.apache.asterix.lang.common.clause.WhereClause;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
 import org.apache.asterix.lang.common.rewrites.VariableSubstitutionEnvironment;
+import org.apache.asterix.lang.common.util.VariableCloneAndSubstitutionUtil;
 import org.apache.asterix.lang.common.visitor.CloneAndSubstituteVariablesVisitor;
 import org.apache.asterix.lang.sqlpp.clause.AbstractBinaryCorrelateClause;
 import org.apache.asterix.lang.sqlpp.clause.FromClause;
@@ -47,6 +48,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationInput;
@@ -377,4 +379,17 @@ public class SqlppCloneAndSubstituteVariablesVisitor extends CloneAndSubstituteV
         return new Pair<>(newSubquery, p.second);
     }
 
+    @Override
+    public Pair<ILangExpression, VariableSubstitutionEnvironment> visit(CaseExpression caseExpr,
+            VariableSubstitutionEnvironment env) throws AsterixException {
+        Expression conditionExpr = (Expression) caseExpr.getConditionExpr().accept(this, env).first;
+        List<Expression> whenExprList =
+                VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getWhenExprs(), env, this);
+        List<Expression> thenExprList =
+                VariableCloneAndSubstitutionUtil.visitAndCloneExprList(caseExpr.getThenExprs(), env, this);
+        Expression elseExpr = (Expression) caseExpr.getElseExpr().accept(this, env).first;
+        CaseExpression newCaseExpr = new CaseExpression(conditionExpr, whenExprList, thenExprList, elseExpr);
+        return new Pair<>(newCaseExpr, env);
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/c8c067c5/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
index 2dca532..0363e20 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/visitor/SqlppFormatPrintVisitor.java
@@ -41,6 +41,7 @@ import org.apache.asterix.lang.sqlpp.clause.SelectElement;
 import org.apache.asterix.lang.sqlpp.clause.SelectRegular;
 import org.apache.asterix.lang.sqlpp.clause.SelectSetOperation;
 import org.apache.asterix.lang.sqlpp.clause.UnnestClause;
+import org.apache.asterix.lang.sqlpp.expression.CaseExpression;
 import org.apache.asterix.lang.sqlpp.expression.IndependentSubquery;
 import org.apache.asterix.lang.sqlpp.expression.SelectExpression;
 import org.apache.asterix.lang.sqlpp.struct.SetOperationRight;
@@ -307,4 +308,25 @@ public class SqlppFormatPrintVisitor extends FormatPrintVisitor implements ISqlp
         return null;
     }
 
+    @Override
+    public Void visit(CaseExpression caseExpr, Integer step) throws AsterixException {
+        out.print(skip(step) + "case ");
+        caseExpr.getConditionExpr().accept(this, step + 2);
+        out.println();
+        List<Expression> whenExprs = caseExpr.getWhenExprs();
+        List<Expression> thenExprs = caseExpr.getThenExprs();
+        for (int index = 0; index < whenExprs.size(); ++index) {
+            out.print(skip(step) + "when ");
+            whenExprs.get(index).accept(this, step + 2);
+            out.print(" then ");
+            thenExprs.get(index).accept(this, step + 2);
+            out.println();
+        }
+        out.print(skip(step) + "else ");
+        caseExpr.getElseExpr().accept(this, step + 2);
+        out.println();
+        out.println(skip(step) + "end");
+        return null;
+    }
+
 }