/* ---- This file is part of SECONDO. Copyright (C) 2004, University in Hagen, Department of Computer Science, Database Systems for New Applications. SECONDO is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. SECONDO is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with SECONDO; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ---- August 2008, Burkart Poneleit. Initial Version This file provides a framework to execute TPC-Benchmarks. All queries for the benchmark should be asserted as facts tpc(Benchmark, QueryDefinition). Currently this file contains the definition of all TPC-D queries. Before executing a benchmark, the predicate initialize has to be called exactly once to create the result relation. The result relation will contain the runtime of all intermediate steps of the optimizer, total runtime for the query and flags, which indicate whether the step of the optimizer succeeded or failed. Executing a benchmark is as simple as calling the predicate ---- executeBenchmark(Benchmark) ---- where Benchmark is d, h or whatever TPC-Benchmark you want to run. On finishing the benchmark run an additional entry is created in the result relation to give you the total runtime for the benchmark run. ---- executeSingleQuery(Benchmark, QueryNumber) ---- To just run a single query and still get the corresponding results such as runtime for the intermediate steps of the optimizer, you can use the predicate executeSingleQuery/2 */ :- dynamic(queryValidation/0). :- assert(queryValidation). /* To skip certain queries when executing a benchmark, a fact ---- skipQuery(Benchmark, QueryNumber) ---- can be asserted. */ :- dynamic(skipQuery/2). :- assert(skipQuery(d, 1)), assert(skipQuery(d, 3)), assert(skipQuery(d, 5)), assert(skipQuery(d, 6)), assert(skipQuery(d, 8)), assert(skipQuery(d, 10)), assert(skipQuery(d, 11)), assert(skipQuery(d, 12)), assert(skipQuery(d, 13)), assert(skipQuery(d, 14)), assert(skipQuery(d, 15)), assert(skipQuery(d, 18)), assert(skipQuery(d, 19)). /* Results of the benchmark runs are kept in a relation in the database. Standard name for this relation is benchmarkResult. This can be changed by retracting the fact resultRelation and reasserting it with a different name. To create the relation the predicate initialize has to be called. It creates the relation and inserts a "Dummy" entry, as correct handling of empty relation in Secondo optimizer is still wonting. */ :- dynamic(resultRelation/1). :- assert(resultRelation(benchmarkResult)). :- dynamic(maxRunTime/1). initialize :- resultRelation(Rel), my_concat_atom([Rel, ' = [const rel(tuple([Query: string,', 'Setup: bool, ', 'Rewrite: bool, ', 'Lookup: bool, ', 'QueryToPlan: bool, ', 'planToAtom: bool, ', 'Execute: bool, ', 'Teardown: bool, ', 'runtime_Rewrite: duration, ', 'runtime_Lookup: duration, ', 'runtime_QueryToPlan: duration, ', 'runtime_planToAtom: duration, ', 'runtime_Execute: duration, ', 'runtime_Total: duration, ', 'Date: instant]))', ' value (("Dummy" FALSE FALSE FALSE ', 'FALSE FALSE FALSE FALSE (0 0) (0 0) (0 0) ', '(0 0) (0 0) (0 0) -1))]'], Query), let(Query). initialize :- nl, write('Please assert resultRelation()'). time(Begin, Duration) :- get_time(End), Time is End - Begin, my_convert_time(Time, _, _, _, Hour, Minute, Sec, MilliSec), my_convert_time(0, _, _, _, H, _, _, _), Hour1 is Hour - H, Duration is (Hour1 * 3600000) + (Minute * 60000) + (Sec * 1000) + MilliSec. tpc(Benchmark, No) :- skipQuery(Benchmark, No), upcase_atom(Benchmark, BMOut), my_concat_atom(['\nTPC-', BMOut, ' ', No, '\n\tSkipped'], Result), my_concat_atom([Benchmark, No], Key), ( retractall(benchmarkResult(Key, _)) ; true ), assert(benchmarkResult(Key, Result)). tpc(Benchmark, No) :- resultRelation(Rel), upcase_atom(Benchmark, BMOut), my_concat_atom(['"TPC-', BMOut, ' ', No, '"'], QueryName), my_string_to_atom(QueryString, QueryName), sql insert into Rel values [QueryString, false, false, false, false, false, false, false, create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), instant(0)], get_time(BeginAll), catch( ((setupQuery(Benchmark, No) ) -> ( SetupResult = '', sql update Rel set [setup = true] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tSetup failed', '\n'], SetupResult) ), _, my_concat_atom(['\tSetup failed', '\n'], SetupResult)), tpc(Benchmark, No, Query), catch( (ground(Query), get_time(BeginRewrite), (rewriteQuery(Query, RQuery)) -> ( RewriteResult = '', time(BeginRewrite, TRewrite), sql update Rel set [rewrite = true, runtime_Rewrite = create_duration(0, TRewrite)] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tRewrite failed', '\n'], RewriteResult) ), _, my_concat_atom(['\tRewrite failed', '\n'], RewriteResult)), catch( ((ground(RQuery), get_time(BeginLookup), callLookup(RQuery, Query2)) -> ( LookupResult = '', time(BeginLookup, TLookup), sql update Rel set [lookup = true, runtime_Lookup = create_duration(0, TLookup)] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tLookup failed', '\n'], LookupResult) ), _, my_concat_atom(['\tLookup failed', '\n'], LookupResult)), !, catch( ((ground(Query2), get_time(BeginQTP), queryToPlan(Query2, Plan, _)) -> ( QueryToPlanResult = '', time(BeginQTP, TQTP), sql update Rel set [queryToPlan = true, runtime_QueryToPlan = create_duration(0, TQTP)] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tQueryToPlan failed', '\n'], QueryToPlanResult) ), _, my_concat_atom(['\tQueryToPlan failed', '\n'], QueryToPlanResult)), !, catch( ((ground(Plan), get_time(BeginPTA), plan_to_atom(Plan, QueryOut)) -> ( PlanToAtomResult = '', time(BeginPTA, TPTA), sql update Rel set [planToAtom = true, runtime_PlanToAtom = create_duration(0, TPTA)] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tPlanToAtom failed', '\n'], PlanToAtomResult) ), _, my_concat_atom(['\tPlanToAtom failed', '\n'], PlanToAtomResult)), (( ground(QueryOut), get_time(BeginExec), my_concat_atom(['query ', QueryOut], QueryText) ) ; true), catch( ((ground(QueryOut), secondo(QueryText)) -> ( ExecuteResult = '', time(BeginExec, TExec), sql update Rel set [execute = true, runtime_Execute = create_duration(0, TExec)] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tExecute failed', '\n'], ExecuteResult) ), _, my_concat_atom(['\tExecute failed', '\n'], ExecuteResult)), catch( (teardownQuery(Benchmark, No) -> ( TeardownResult = '', sql update Rel set [teardown = true] where [date = instant(0), (query) = QueryString] ) ; my_concat_atom(['\tTeardown failed', '\n'], TeardownResult) ), _, my_concat_atom(['\tTeardown failed', '\n'], TeardownResult)), my_concat_atom(['\nTPC-', BMOut, ' ', No, '\n', SetupResult, RewriteResult , LookupResult , QueryToPlanResult , PlanToAtomResult , ExecuteResult , TeardownResult], Result), time(BeginAll, TotalTime), sql update Rel set [runtime_Total = create_duration(0, TotalTime)] where [date = instant(0), (query) = QueryString], my_concat_atom([Benchmark, No], Key), ( retractall(benchmarkResult(Key, _)) ; true ), assert(benchmarkResult(Key, Result)). tpc(d, No, Query) :- tpcd(No, Query). executeSingleQuery(Benchmark, No) :- executeQuery(Benchmark, No), resultRelation(Rel), !, let('tempXXXXXXX = now()'), !, sql update Rel set [date = tempXXXXXXX] where [date = instant(0)], !, delete(tempXXXXXXX). executeQuery(Benchmark, No) :- tpc(Benchmark, No). executeQueries(_, []). executeQueries(Benchmark, [[No, _] | Rest]) :- executeQuery(Benchmark, No), % dc(tpcd, ( % N is No + 1, % write_list(['\nExecute next Query (', N, ')? y/n']), % get_single_char(Answer), % Answer = 121 )), executeQueries(Benchmark, Rest). executeBenchmark(Benchmark) :- get_time(Begin), resultRelation(Rel), sql delete from Rel where date = instant(0), setupBenchmark(Benchmark), retractall(benchmarkResult(_, _)), findall([No, Query], tpc(Benchmark, No, Query), Queries), executeQueries(Benchmark, Queries), !, time(Begin, Total), upcase_atom(Benchmark, BMOut), my_concat_atom(['"TPC-', BMOut, '"'], BMName), my_string_to_atom(BMString, BMName), let('tempXXXXXXX = now()'), sql insert into Rel values [BMString, false, false, false, false, false, false, false, create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, 0), create_duration(0, Total), instant(0)], sql update Rel set [date = tempXXXXXXX] where [date = instant(0)], delete(tempXXXXXXX), findall(Result, benchmarkResult(_, Result), L), nl, write_list(L). /* Run Tpcd Queries and export Benchmark results to csv. */ runAnalysis(Database) :- ( cdb ; true ), odb(Database), ( initialize ; true ), sql(delete from benchmarkResult where (query) contains "T"), ( delete(tempXXXXXXX) ; true ), !, setOption(subqueryUnnesting), executeBenchmark(d), !, executeBenchmark(d), !, delOption(subqueryUnnesting), executeBenchmark(d), !, executeBenchmark(d), !, setOption(subqueryUnnesting), retractall(skipQuery(d, 15)), executeSingleQuery(d, 15), !, executeSingleQuery(d, 15), !, delOption(subqueryUnnesting), executeSingleQuery(d, 15), !, executeSingleQuery(d, 15), !, assert(skipQuery(d, 15)), setOption(subqueryUnnesting), get_time(A), my_convert_time(A, Y, M, D, _, _, _, _), my_concat_atom(['benchmarkResult feed csvexport[\'Analyse ', Database, '-', Y, '-', M, '-', D, '.csv\', FALSE, TRUE, ";"] count'], Query), write('ExportQuery: '), write(Query), nl, !, query(Query). /* Any operations which must happen before a query is run should be coded as a predicate. The predicate is automatically called when using executeSingleQuery/2 or runBenchmark/1. Currently used to emulate views for Query 15 of TPC-D benchmark. ---- setupQuery(Benchmark, QueryNumber) ---- */ setupQuery(d, 15) :- ( teardownQuery(d, 15) ; true ), let(revenue, select [lsuppkey as supplier_no, sum(lextendedprice * (1 - ldiscount)) as total_revenue] from lineitem where [lshipdate >= instant("1996-01-01"), lshipdate < theInstant( year_of(instant("1996-01-01")), month_of(instant("1996-01-01")) + 3, day_of(instant("1996-01-01")))] groupby [lsuppkey]). setupQuery(_,_). /* Any operations to clean up after a query should be coded as a predicate. Currently used to emulate views for Query 15 of TPC-D benchmark. ---- teardownQuery(Benchmark, QueryNumber) ---- */ teardownQuery(d, 15) :- catch(drop_relation(revenue), _, true). teardownQuery(_, _). /* The idea behind setupBenchmark/1 is to assert all facts for substitution parameters and to determine the substitution parameters at runtime iff queryValidation is asserted. If queryValidation is asserted the substitution parameters are the values for query validation according to the benchmark. */ setupBenchmark(d) :- not(queryValidation), retractall(region(_,_)), assert(region(0, "AFRICA")), assert(region(1, "AMERICA")), assert(region(2, "ASIA")), assert(region(3, "EUROPE")), assert(region(4, "MIDDLE EAST")), retractall(typeSyllable1(_,_)), assert(typeSyllable1(0, "STANDARD")), assert(typeSyllable1(1, "SMALL")), assert(typeSyllable1(2, "MEDIUM")), assert(typeSyllable1(3, "LARGE")), assert(typeSyllable1(4, "ECONOMY")), assert(typeSyllable1(5, "PROMO")), retractall(typeSyllable2(_,_)), assert(typeSyllable2(0, "ANODIZED")), assert(typeSyllable2(1, "BURNISHED")), assert(typeSyllable2(2, "PLATED")), assert(typeSyllable2(3, "POLISHED")), assert(typeSyllable2(4, "BRUSHED")), retractall(typeSyllable3(_,_)), assert(typeSyllable3(0, "TIN")), assert(typeSyllable3(1, "NICKEL")), assert(typeSyllable3(2, "BRASS")), assert(typeSyllable3(3, "STEEL")), assert(typeSyllable3(4, "COPPER")). setupBenchmark(_). /* The Queries defined for TPC-D Benchmark. Queries with syntax currently not understood are commented out. */ tpcd(1, select [lreturnflag, llinestatus, sum(lquantity) as sum_qty, sum(lextendedprice) as sum_base_price, sum(lextendedprice*(1-ldiscount)) as sum_disc_price, sum(lextendedprice*(1-ldiscount)*(1+ltax)) as sum_charge, avg(lquantity) as avg_qty, avg(lextendedprice) as avg_price, avg(ldiscount) as avg_disc, count(*) as count_order] from lineitem where % substitution parameter [lshipdate <= create_instant(instant2real(instant("1998-12-01")) - Delta)] % [lshipdate <= instant("1998-09-02")] groupby [lreturnflag, llinestatus] orderby [lreturnflag, llinestatus]) :- % Delta is randomly selected within [60 - 120] queryValidation -> ( Delta is 90.0 ) ; ( Delta is random(60.0) + 60.0 ). tpcd(2, select [sacctbal, sname, nname, ppartkey, pmfgr, saddress, sphone, scomment] from [part, supplier, partsupp, nation, region] where [ppartkey = pspartkey, ssuppkey = pssuppkey, % substitution parameter % psize = 15, psize = Size, % substitution parameter % ptype like "%BRASS" % ptype contains "BRASS", ptype contains Type, snationkey = nnationkey, nregionkey = rregionkey, % substitution parameter % rname = "EUROPE", rname = Region, pssupplycost = ( select min(ps:pssupplycost) from [partsupp as ps, supplier as s, nation as n, region as r] where [ppartkey = ps:pspartkey, s:ssuppkey = ps:pssuppkey, s:snationkey = n:nnationkey, n:nregionkey = r:rregionkey, % substitution parameter % rname = "EUROPE"] r:rname = Region] )] orderby[ sacctbal desc, nname, sname, ppartkey] first 100) :- queryValidation -> ( Size is 15, Type = "BRASS", Region = "EUROPE" ) ; ( Size is random(49) + 1, T is random(5), typeSyllable3(T, Type), R is random(4), region(R, Region)). tpcd(3, select [lorderkey, sum(lextendedprice*(1-ldiscount)) as revenue, oorderdate, oshippriority] from [customer, orders, lineitem] where % substitution parameter [cmktsegment = "BUILDING", ccustkey = ocustkey, lorderkey = oorderkey, % substitution parameter oorderdate < instant("1995-03-15"), % substitution parameter lshipdate > instant("1995-03-15")] groupby [lorderkey, oorderdate, oshippriority] orderby [revenue desc, oorderdate] first 10). tpcd(4, select [oorderpriority, count(*) as ordercount] from orders where % substitution parameter [oorderdate >= instant("1993-07-01"), % substitution parameter oorderdate < theInstant( year_of(instant("1993-07-01")), month_of(instant("1993-07-01")) + 3, day_of(instant("1993-07-01"))), exists( select * from lineitem where [lorderkey = oorderkey, lcommitdate < lreceiptdate]) ] groupby [oorderpriority] orderby [oorderpriority]). tpcd(5, select [nname, sum(lextendedprice * (1 - ldiscount)) as revenue] from [customer, orders, lineitem, supplier, nation, region] where [ccustkey = ocustkey, oorderkey = lorderkey, lsuppkey = ssuppkey, cnationkey = snationkey, snationkey = nnationkey, nregionkey = rregionkey, % substitution parameter rname = "ASIA", % substitution parameter oorderdate >= instant("1994-01-01"), % substitution parameter oorderdate < theInstant( year_of(instant("1994-01-01")) + 1, month_of(instant("1994-01-01")) , day_of(instant("1994-01-01")))] groupby [nname] orderby [revenue desc]). tpcd(6, select [sum(lextendedprice*ldiscount) as revenue] from lineitem where % substitution parameter [lshipdate >= instant("1994-01-01"), % substitution parameter lshipdate < theInstant( year_of(instant("1994-01-01")) + 1, month_of(instant("1994-01-01")) , day_of(instant("1994-01-01"))), % substitution parameter between(ldiscount, 0.06 - 0.01, 0.06 + 0.01), % substitution parameter lquantity < 24] groupby[]). tpcd(7, select [supp_nation, cust_nation, lyear, sum(volume) as revenue] from ( select [n1:nname as supp_nation, n2:nname as cust_nation, year_of(lshipdate) as lyear, lextendedprice * (1 - ldiscount) as volume] from [supplier, lineitem, orders, customer, nation as n1, nation as n2] where [ssuppkey = lsuppkey, oorderkey = lorderkey, ccustkey = ocustkey, snationkey = n1:nnationkey, cnationkey = n2:nnationkey, % substitution parameter (n1:nname = "FRANCE" and n2:nname = "GERMANY") % substitution parameter or (n1:nname = "GERMANY" and n2:nname = "FRANCE"), between(instant2real(lshipdate), instant2real(instant("1995-01-01")), instant2real(instant("1996-12-31")))] ) as shipping groupby [supp_nation, cust_nation, lyear] orderby [supp_nation, cust_nation, lyear]). /* Q8 does not work, arbitrary expressions over aggregations cannot be translated at the moment. */ tpcd(8, select [oyear, /* sum(case when nation = "BRAZIL" then volume else 0 end) / sum(volume) as mktshare */ (aggregate((ifthenelse(nation = "BRAZIL", volume, 0.0)), (+), 'real', const(real,0.0)) / sum(volume)) as mktshare ] from ( select [year_of(oorderdate) as oyear, lextendedprice * (1-ldiscount) as volume, n2:nname as nation] from [part, supplier, lineitem, orders, customer, nation as n1, nation as n2, region] where [ppartkey = lpartkey, ssuppkey = lsuppkey, lorderkey = oorderkey, ocustkey = ccustkey, cnationkey = n1:nnationkey, n1:nregionkey = rregionkey, % substitution parameter rname = "AMERICA", snationkey = n2:nnationkey, between(instant2real(oorderdate), instant2real(instant("1995-01-01")), instant2real(instant("1996-12-31"))), % substitution parameter ptype = "ECONOMY ANODIZED STEEL"] ) as allnations groupby [oyear] orderby [oyear]). tpcd(9, select [nation, oyear, sum(amount) as sumprofit] from ( select [nname as nation, year_of(oorderdate) as oyear, lextendedprice * (1 - ldiscount) - pssupplycost * lquantity as amount] from [part, supplier, lineitem, partsupp, orders, nation] where [ssuppkey = lsuppkey, pssuppkey = lsuppkey, pspartkey = lpartkey, ppartkey = lpartkey, oorderkey = lorderkey, snationkey = nnationkey, % substitution parameter pname contains "green"] ) as profit groupby [nation, oyear] orderby [nation, oyear desc]). tpcd(10, select [ccustkey, cname, sum(lextendedprice * (1 - ldiscount)) as revenue, cacctbal, nname, caddress, cphone, ccomment] from [customer, orders, lineitem, nation] where [ccustkey = ocustkey, lorderkey = oorderkey, oorderdate >= instant("1993-10-01"), oorderdate < theInstant( year_of(instant("1993-10-01")), month_of(instant("1993-10-01")) + 3, day_of(instant("1993-10-01"))), lreturnflag = "R", cnationkey = nnationkey] groupby [ccustkey, cname, cacctbal, cphone, nname, caddress, ccomment] orderby [revenue desc] first 20). /* Q11 is only partially working, implementation for the having clause is still missing. */ tpcd(11, select [pspartkey, (sum(pssupplycost * psavailqty)) as value] from [partsupp, supplier, nation] where [pssuppkey = ssuppkey, snationkey = nnationkey, % substitution parameter nname = "GERMANY"] groupby [pspartkey] /* having [sum(pssupplycost * psavailqty) > ( select % substitution parameter [sum(pssupplycost * psavailqty * 0.0001)] from [partsupp, supplier, nation] where [pssuppkey = ssuppkey, snationkey = nnationkey, nname = "GERMANY"] ) ]*/ orderby [value desc]). tpcd(12, select /* sum(case when oorderpriority ="1-URGENT" or oorderpriority ="2-HIGH" then 1 else 0 end) as highlinecount, sum(case when oorderpriority <> "1-URGENT" and oorderpriority <> "2-HIGH" then 1 else 0 end) as lowlinecount*/ [lshipmode, aggregate((ifthenelse(oorderpriority = "1-URGENT" or oorderpriority = "2-HIGH", 1, 0)), (+), 'int', [const,int,value,0]) as highlinecount, aggregate((ifthenelse(not(oorderpriority = "1-URGENT") and not(oorderpriority = "2-HIGH"), 1, 0)), (+), 'int', [const,int,value,0]) as lowlinecount ] from [orders, lineitem] where [oorderkey = lorderkey, % substitution parameter lshipmode in ("MAIL", "SHIP"), % lshipmode = "MAIL" or lshipmode = "SHIP", lcommitdate < lreceiptdate, lshipdate < lcommitdate, % substitution parameter lreceiptdate >= instant("1994-01-01"), % substitution parameter lreceiptdate < theInstant( year_of(instant("1994-01-01")) + 1, month_of(instant("1994-01-01")), day_of(instant("1994-01-01")))] groupby [lshipmode] orderby [lshipmode]). /* Q13 does not work, no implementation of left outerjoin */ tpcd(13, _). /* tpcd(13, select [ccount, count(*) as custdist] from ( select [ccustkey, count(oorderkey)] from customer left outer join orders on [ccustkey = ocustkey and ocomment not like "%[WORD1]%[WORD2]%"] groupby [ccustkey] )as corders (ccustkey, ccount) groupby [ccount] orderby [custdist desc, ccount desc]). Q14Does not work, arbitrary expressions over aggregation aren't translated */ tpcd(14, select /* [100.00 * sum(case when ptype like "PROMO%" then lextendedprice*(1-ldiscount) else 0 end) / sum(lextendedprice * (1 - ldiscount)) as promo_revenue]*/ [(aggregate(((ifthenelse(ptype starts "PROMO", lextendedprice*(1-ldiscount), 0)) * 100.0), (+), 'real', [const,real,value,0.0]) / sum(lextendedprice * (1 - ldiscount))) as promo_revenue] from [lineitem, part] where [lpartkey = ppartkey, lshipdate >= instant("1995-09-01"), lshipdate < theInstant( year_of(instant("1995-09-01")), month_of(instant("1995-09-01")) + 1, day_of(instant("1995-09-01")))] groupby[]). /* Implementation only partially correct. The view is emulated by a temporary relation. */ tpcd(15, % Query) :- /* create view revenue[STREAM_ID] (supplier_no, total_revenue) as select l_suppkey, sum(l_extendedprice * (1 - l_discount)) from lineitem where l_shipdate >= date "[DATE]" and l_shipdate < date "[DATE]" + interval "3" month group by l_suppkey;*/ select [ssuppkey, sname, saddress, sphone, total_revenue] from [supplier, revenue/*[STREAMID]*/] where [ssuppkey = supplier_no, total_revenue = ( select max(r:total_revenue) from revenue as r/*[STREAMID]*/ )] orderby [ssuppkey]) /* drop view revenue[STREAM_ID]; */. tpcd(16, select [pbrand, ptype, psize, count(distinct pssuppkey) as suppliercnt] from [partsupp, part] where [ppartkey = pspartkey, % substitution parameter not(pbrand = "Brand#45"), % substitution parameter not(ptype starts "MEDIUM POLISHED"), % substitution parameters psize in (49, 14, 23, 45, 19, 3, 36, 9), pssuppkey not in( select ssuppkey from supplier where % scomment like "%Customer%Complaints%" [scomment contains "Customer", scomment contains "Complaints"] )] groupby [pbrand, ptype, psize] orderby [suppliercnt desc, pbrand, ptype, psize]). tpcd(17, select [sum(lextendedprice / 7.0) as avg_yearly] from [lineitem, part] where [ppartkey = lpartkey, pbrand = "Brand#23", pcontainer = "MED BOX", lquantity < ( select avg(0.2 * l1:lquantity) from [lineitem as l1] where [l1:lpartkey = ppartkey] )] groupby []). /* Q18 is only partially working, implementation of the having clause is still missing. */ tpcd(18, select [cname, ccustkey, oorderkey, oorderdate, ototalprice, sum(lquantity) as quant] from [customer, orders, lineitem] where [oorderkey in ( select lorderkey from lineitem /* groupby [lorderkey having % substitution parameter sum(lquantity) > 300] */ ), ccustkey = ocustkey, oorderkey = lorderkey] groupby [cname, ccustkey, oorderkey, oorderdate, ototalprice] orderby [ototalprice desc, oorderdate]). tpcd(19, select [(sum(lextendedprice * (1 - ldiscount) )) as revenue] from [lineitem, part] where [(( ( ( ( ( ( ( ( (ppartkey = lpartkey) % substitution parameter and (pbrand = "Brand#12") ) and (pcontainer in ( "SM CASE", "SM BOX", "SM PACK", "SM PKG")) ) % substitution parameter and (lquantity >= 1) ) % substitution parameter and (lquantity <= 1 + 10) ) and (between(psize, 1, 5)) ) and (lshipmode in ("AIR", "AIR REG")) ) and (lshipinstruct = "DELIVER IN PERSON") ) ) or ( ( ( ( ( ( ( ( (ppartkey = lpartkey) % substitution parameter and (pbrand = "Brand#23") ) and (pcontainer in ("MED BAG", "MED BOX", "MED PKG", "MED PACK")) ) % substitution parameter and (lquantity >= 10) ) % substitution parameter and (lquantity <= 10 + 10) ) and (between(psize, 1, 10)) ) and (lshipmode in ("AIR", "AIR REG")) % and (lshipmode = "AIR" or lshipmode = "AIR REG") ) and (lshipinstruct = "DELIVER IN PERSON") ) )) or ( ( ( ( ( ( ( ( (ppartkey = lpartkey) % substitution parameter and (pbrand = "Brand#34") ) and (pcontainer in ( "LG CASE", "LG BOX", "LG PACK", "LG PKG")) ) % substitution parameter and (lquantity >= 20) ) % substitution parameter and (lquantity <= 20 + 10) ) and (between(psize, 1, 15)) ) and (lshipmode in ("AIR", "AIR REG")) ) and (lshipinstruct = "DELIVER IN PERSON") ) )] groupby[]). tpcd(20, select [sname, saddress] from [supplier, nation] where [ssuppkey in ( select [pssuppkey] from [partsupp] where [pspartkey in ( select ppartkey from part where % pname like '[COLOR]%' % substitution parameter tostring(pname) starts "forest" ), psavailqty > ( select sum(lquantity * 0.5) from lineitem where [lpartkey = pspartkey, lsuppkey = pssuppkey, % substitution parameter lshipdate >= instant("1994-01-01"), % substitution parameter lshipdate < theInstant( year_of(instant("1994-01-01")) + 1, month_of(instant("1994-01-01")), day_of(instant("1994-01-01")))] )] ), snationkey = nnationkey, % substitution parameter nname = "CANADA"] orderby [sname]). tpcd(21, select [sname, count(*) as numwait] from [supplier, lineitem as l1, orders, nation] where [ssuppkey = l1:lsuppkey, oorderkey = l1:lorderkey, oorderstatus = "F", l1:lreceiptdate > l1:lcommitdate, exists( select * from lineitem as l2 where [l2:lorderkey = l1:lorderkey, not(l2:lsuppkey = l1:lsuppkey)] ), not(exists( select * from lineitem as l3 where [l3:lorderkey = l1:lorderkey, not(l3:lsuppkey = l1:lsuppkey), l3:lreceiptdate > l3:lcommitdate] )), snationkey = nnationkey, % substitution parameter nname = "SAUDI ARABIA"] groupby [sname] orderby [numwait desc, sname] first 100). tpcd(22, select [cntrycode, count(*) as numcust, sum(cacctbal) as totacctbal] from ( select [substr(cphone, 1, 2) as cntrycode, cacctbal] from customer where [substr(cphone, 1, 2) in % substitution parameters ("13","35","31","23","29","30","18"), cacctbal > ( select avg(c1:cacctbal) from customer as c1 where [c1:cacctbal > 0.00, substr(c1:cphone, 1, 2) in % substitution parameter ("13","35","31","23","29","30","18")] ), not( exists( select * from orders where ocustkey = ccustkey ))] ) as custsale groupby [cntrycode] orderby [cntrycode]).