/*
 * 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.
 */


DROP dataverse tpch IF EXISTS;
CREATE  dataverse tpch;

USE tpch;


CREATE TYPE LineItemType AS {
  l_linenumber : int32
}

CREATE TYPE OrderType AS {
  o_orderkey : int32
}

CREATE DATASET LineItem(LineItemType) PRIMARY KEY l_linenumber;

CREATE DATASET Orders(OrderType) PRIMARY KEY o_orderkey;

/** The plan tests that the expression for different switch-case branches are not extracted.*/
SELECT l.l_shipmode,
       sum(CASE
             WHEN o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH' THEN 1 +  o.o_orderpriority * 0
             ELSE 0 + o.o_orderpriority * 0
           END) high_line_count,
       sum(CASE o.o_orderpriority = '1-URGENT' or o.o_orderpriority = '2-HIGH'
             WHEN true THEN 0 + o.o_orderpriority * 0
             ELSE 1 +  o.o_orderpriority * 0
           END) low_line_count
FROM  LineItem l,
      Orders o
WHERE o.o_orderkey = l.l_orderkey AND l.l_commitdate < l.l_receiptdate AND
      l.l_shipdate < l.l_commitdate AND l.l_receiptdate >= '1994-01-01' AND
      l.l_receiptdate < '1995-01-01' AND (l.l_shipmode = 'MAIL' OR l.l_shipmode = 'SHIP')
GROUP BY l.l_shipmode
ORDER BY l.l_shipmode
;
