1 | /* |
2 | * Legal Notice |
3 | * |
4 | * This document and associated source code (the "Work") is a part of a |
5 | * benchmark specification maintained by the TPC. |
6 | * |
7 | * The TPC reserves all right, title, and interest to the Work as provided |
8 | * under U.S. and international laws, including without limitation all patent |
9 | * and trademark rights therein. |
10 | * |
11 | * No Warranty |
12 | * |
13 | * 1.1 TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE INFORMATION |
14 | * CONTAINED HEREIN IS PROVIDED "AS IS" AND WITH ALL FAULTS, AND THE |
15 | * AUTHORS AND DEVELOPERS OF THE WORK HEREBY DISCLAIM ALL OTHER |
16 | * WARRANTIES AND CONDITIONS, EITHER EXPRESS, IMPLIED OR STATUTORY, |
17 | * INCLUDING, BUT NOT LIMITED TO, ANY (IF ANY) IMPLIED WARRANTIES, |
18 | * DUTIES OR CONDITIONS OF MERCHANTABILITY, OF FITNESS FOR A PARTICULAR |
19 | * PURPOSE, OF ACCURACY OR COMPLETENESS OF RESPONSES, OF RESULTS, OF |
20 | * WORKMANLIKE EFFORT, OF LACK OF VIRUSES, AND OF LACK OF NEGLIGENCE. |
21 | * ALSO, THERE IS NO WARRANTY OR CONDITION OF TITLE, QUIET ENJOYMENT, |
22 | * QUIET POSSESSION, CORRESPONDENCE TO DESCRIPTION OR NON-INFRINGEMENT |
23 | * WITH REGARD TO THE WORK. |
24 | * 1.2 IN NO EVENT WILL ANY AUTHOR OR DEVELOPER OF THE WORK BE LIABLE TO |
25 | * ANY OTHER PARTY FOR ANY DAMAGES, INCLUDING BUT NOT LIMITED TO THE |
26 | * COST OF PROCURING SUBSTITUTE GOODS OR SERVICES, LOST PROFITS, LOSS |
27 | * OF USE, LOSS OF DATA, OR ANY INCIDENTAL, CONSEQUENTIAL, DIRECT, |
28 | * INDIRECT, OR SPECIAL DAMAGES WHETHER UNDER CONTRACT, TORT, WARRANTY, |
29 | * OR OTHERWISE, ARISING IN ANY WAY OUT OF THIS OR ANY OTHER AGREEMENT |
30 | * RELATING TO THE WORK, WHETHER OR NOT SUCH AUTHOR OR DEVELOPER HAD |
31 | * ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. |
32 | * |
33 | * Contributors: |
34 | * Gradient Systems |
35 | */ |
36 | #include "config.h" |
37 | #include "porting.h" |
38 | #include <stdio.h> |
39 | #include "pricing.h" |
40 | #include "w_web_sales.h" |
41 | #include "w_web_returns.h" |
42 | #include "date.h" |
43 | #include "decimal.h" |
44 | #include "genrand.h" |
45 | #include "build_support.h" |
46 | #include "misc.h" |
47 | #include "tables.h" |
48 | #include "constants.h" |
49 | #include "nulls.h" |
50 | #include "tdefs.h" |
51 | #include "scaling.h" |
52 | #include "permute.h" |
53 | #include "scd.h" |
54 | #include "parallel.h" |
55 | |
56 | #include "append_info.h" |
57 | |
58 | struct W_WEB_SALES_TBL g_w_web_sales; |
59 | ds_key_t skipDays(int nTable, ds_key_t *pRemainder); |
60 | |
61 | static ds_key_t kNewDateIndex = 0; |
62 | static ds_key_t jDate; |
63 | static int nItemIndex = 0; |
64 | |
65 | /* |
66 | * the validation process requires generating a single lineitem |
67 | * so the main mk_xxx routine has been split into a master record portion |
68 | * and a detail/lineitem portion. |
69 | */ |
70 | static void mk_master(void *info_arr, ds_key_t index) { |
71 | static decimal_t dMin, dMax; |
72 | int nGiftPct; |
73 | struct W_WEB_SALES_TBL *r; |
74 | static int bInit = 0, nItemCount; |
75 | |
76 | r = &g_w_web_sales; |
77 | |
78 | if (!bInit) { |
79 | strtodec(&dMin, "1.00" ); |
80 | strtodec(&dMax, "100000.00" ); |
81 | jDate = skipDays(WEB_SALES, &kNewDateIndex); |
82 | nItemCount = (int)getIDCount(ITEM); |
83 | bInit = 1; |
84 | } |
85 | |
86 | /*** |
87 | * some attributes reamin the same for each lineitem in an order; others are |
88 | * different for each lineitem. Since the number of lineitems per order is |
89 | * static, we can use a modulo to determine when to change the semi-static |
90 | * values |
91 | */ |
92 | while (index > kNewDateIndex) /* need to move to a new date */ |
93 | { |
94 | jDate += 1; |
95 | kNewDateIndex += dateScaling(WEB_SALES, jDate); |
96 | } |
97 | |
98 | r->ws_sold_date_sk = mk_join(WS_SOLD_DATE_SK, DATET, 1); |
99 | r->ws_sold_time_sk = mk_join(WS_SOLD_TIME_SK, TIME, 1); |
100 | r->ws_bill_customer_sk = mk_join(WS_BILL_CUSTOMER_SK, CUSTOMER, 1); |
101 | r->ws_bill_cdemo_sk = mk_join(WS_BILL_CDEMO_SK, CUSTOMER_DEMOGRAPHICS, 1); |
102 | r->ws_bill_hdemo_sk = mk_join(WS_BILL_HDEMO_SK, HOUSEHOLD_DEMOGRAPHICS, 1); |
103 | r->ws_bill_addr_sk = mk_join(WS_BILL_ADDR_SK, CUSTOMER_ADDRESS, 1); |
104 | |
105 | /* most orders are for the ordering customers, some are not */ |
106 | genrand_integer(&nGiftPct, DIST_UNIFORM, 0, 99, 0, WS_SHIP_CUSTOMER_SK); |
107 | if (nGiftPct > WS_GIFT_PCT) { |
108 | r->ws_ship_customer_sk = mk_join(WS_SHIP_CUSTOMER_SK, CUSTOMER, 2); |
109 | r->ws_ship_cdemo_sk = mk_join(WS_SHIP_CDEMO_SK, CUSTOMER_DEMOGRAPHICS, 2); |
110 | r->ws_ship_hdemo_sk = mk_join(WS_SHIP_HDEMO_SK, HOUSEHOLD_DEMOGRAPHICS, 2); |
111 | r->ws_ship_addr_sk = mk_join(WS_SHIP_ADDR_SK, CUSTOMER_ADDRESS, 2); |
112 | } else { |
113 | r->ws_ship_customer_sk = r->ws_bill_customer_sk; |
114 | r->ws_ship_cdemo_sk = r->ws_bill_cdemo_sk; |
115 | r->ws_ship_hdemo_sk = r->ws_bill_hdemo_sk; |
116 | r->ws_ship_addr_sk = r->ws_bill_addr_sk; |
117 | } |
118 | |
119 | r->ws_order_number = index; |
120 | genrand_integer(&nItemIndex, DIST_UNIFORM, 1, nItemCount, 0, WS_ITEM_SK); |
121 | |
122 | return; |
123 | } |
124 | |
125 | static void mk_detail(void *info_arr, int bPrint) { |
126 | static int *pItemPermutation, nItemCount, bInit = 0; |
127 | struct W_WEB_SALES_TBL *r; |
128 | int nShipLag, nTemp; |
129 | struct W_WEB_RETURNS_TBL w_web_returns; |
130 | tdef *pT = getSimpleTdefsByNumber(WEB_SALES); |
131 | |
132 | if (!bInit) { |
133 | jDate = skipDays(WEB_SALES, &kNewDateIndex); |
134 | pItemPermutation = makePermutation(NULL, nItemCount = (int)getIDCount(ITEM), WS_PERMUTATION); |
135 | |
136 | bInit = 1; |
137 | } |
138 | |
139 | r = &g_w_web_sales; |
140 | |
141 | nullSet(&pT->kNullBitMap, WS_NULLS); |
142 | |
143 | /* orders are shipped some number of days after they are ordered, |
144 | * and not all lineitems ship at the same time |
145 | */ |
146 | genrand_integer(&nShipLag, DIST_UNIFORM, WS_MIN_SHIP_DELAY, WS_MAX_SHIP_DELAY, 0, WS_SHIP_DATE_SK); |
147 | r->ws_ship_date_sk = r->ws_sold_date_sk + nShipLag; |
148 | |
149 | if (++nItemIndex > nItemCount) |
150 | nItemIndex = 1; |
151 | r->ws_item_sk = matchSCDSK(getPermutationEntry(pItemPermutation, nItemIndex), r->ws_sold_date_sk, ITEM); |
152 | |
153 | /* the web page needs to be valid for the sale date */ |
154 | r->ws_web_page_sk = mk_join(WS_WEB_PAGE_SK, WEB_PAGE, r->ws_sold_date_sk); |
155 | r->ws_web_site_sk = mk_join(WS_WEB_SITE_SK, WEB_SITE, r->ws_sold_date_sk); |
156 | |
157 | r->ws_ship_mode_sk = mk_join(WS_SHIP_MODE_SK, SHIP_MODE, 1); |
158 | r->ws_warehouse_sk = mk_join(WS_WAREHOUSE_SK, WAREHOUSE, 1); |
159 | r->ws_promo_sk = mk_join(WS_PROMO_SK, PROMOTION, 1); |
160 | set_pricing(WS_PRICING, &r->ws_pricing); |
161 | |
162 | /** |
163 | * having gone to the trouble to make the sale, now let's see if it gets |
164 | * returned |
165 | */ |
166 | genrand_integer(&nTemp, DIST_UNIFORM, 0, 99, 0, WR_IS_RETURNED); |
167 | if (nTemp < WR_RETURN_PCT) { |
168 | mk_w_web_returns(&w_web_returns, 1); |
169 | |
170 | struct W_WEB_RETURNS_TBL *rr = &w_web_returns; |
171 | |
172 | void *info = append_info_get(info_arr, WEB_RETURNS); |
173 | append_row_start(info); |
174 | |
175 | append_key(info, rr->wr_returned_date_sk); |
176 | append_key(info, rr->wr_returned_time_sk); |
177 | append_key(info, rr->wr_item_sk); |
178 | append_key(info, rr->wr_refunded_customer_sk); |
179 | append_key(info, rr->wr_refunded_cdemo_sk); |
180 | append_key(info, rr->wr_refunded_hdemo_sk); |
181 | append_key(info, rr->wr_refunded_addr_sk); |
182 | append_key(info, rr->wr_returning_customer_sk); |
183 | append_key(info, rr->wr_returning_cdemo_sk); |
184 | append_key(info, rr->wr_returning_hdemo_sk); |
185 | append_key(info, rr->wr_returning_addr_sk); |
186 | append_key(info, rr->wr_web_page_sk); |
187 | append_key(info, rr->wr_reason_sk); |
188 | append_key(info, rr->wr_order_number); |
189 | append_integer(info, rr->wr_pricing.quantity); |
190 | append_decimal(info, &rr->wr_pricing.net_paid); |
191 | append_decimal(info, &rr->wr_pricing.ext_tax); |
192 | append_decimal(info, &rr->wr_pricing.net_paid_inc_tax); |
193 | append_decimal(info, &rr->wr_pricing.fee); |
194 | append_decimal(info, &rr->wr_pricing.ext_ship_cost); |
195 | append_decimal(info, &rr->wr_pricing.refunded_cash); |
196 | append_decimal(info, &rr->wr_pricing.reversed_charge); |
197 | append_decimal(info, &rr->wr_pricing.store_credit); |
198 | append_decimal(info, &rr->wr_pricing.net_loss); |
199 | |
200 | append_row_end(info); |
201 | } |
202 | |
203 | void *info = append_info_get(info_arr, WEB_SALES); |
204 | append_row_start(info); |
205 | |
206 | append_key(info, r->ws_sold_date_sk); |
207 | append_key(info, r->ws_sold_time_sk); |
208 | append_key(info, r->ws_ship_date_sk); |
209 | append_key(info, r->ws_item_sk); |
210 | append_key(info, r->ws_bill_customer_sk); |
211 | append_key(info, r->ws_bill_cdemo_sk); |
212 | append_key(info, r->ws_bill_hdemo_sk); |
213 | append_key(info, r->ws_bill_addr_sk); |
214 | append_key(info, r->ws_ship_customer_sk); |
215 | append_key(info, r->ws_ship_cdemo_sk); |
216 | append_key(info, r->ws_ship_hdemo_sk); |
217 | append_key(info, r->ws_ship_addr_sk); |
218 | append_key(info, r->ws_web_page_sk); |
219 | append_key(info, r->ws_web_site_sk); |
220 | append_key(info, r->ws_ship_mode_sk); |
221 | append_key(info, r->ws_warehouse_sk); |
222 | append_key(info, r->ws_promo_sk); |
223 | append_key(info, r->ws_order_number); |
224 | append_integer(info, r->ws_pricing.quantity); |
225 | append_decimal(info, &r->ws_pricing.wholesale_cost); |
226 | append_decimal(info, &r->ws_pricing.list_price); |
227 | append_decimal(info, &r->ws_pricing.sales_price); |
228 | append_decimal(info, &r->ws_pricing.ext_discount_amt); |
229 | append_decimal(info, &r->ws_pricing.ext_sales_price); |
230 | append_decimal(info, &r->ws_pricing.ext_wholesale_cost); |
231 | append_decimal(info, &r->ws_pricing.ext_list_price); |
232 | append_decimal(info, &r->ws_pricing.ext_tax); |
233 | append_decimal(info, &r->ws_pricing.coupon_amt); |
234 | append_decimal(info, &r->ws_pricing.ext_ship_cost); |
235 | append_decimal(info, &r->ws_pricing.net_paid); |
236 | append_decimal(info, &r->ws_pricing.net_paid_inc_tax); |
237 | append_decimal(info, &r->ws_pricing.net_paid_inc_ship); |
238 | append_decimal(info, &r->ws_pricing.net_paid_inc_ship_tax); |
239 | append_decimal(info, &r->ws_pricing.net_profit); |
240 | |
241 | append_row_end(info); |
242 | |
243 | return; |
244 | } |
245 | |
246 | /* |
247 | * mk_web_sales |
248 | */ |
249 | int mk_w_web_sales(void *info_arr, ds_key_t index) { |
250 | int nLineitems, i; |
251 | |
252 | /* build the static portion of an order */ |
253 | mk_master(info_arr, index); |
254 | |
255 | /* set the number of lineitems and build them */ |
256 | genrand_integer(&nLineitems, DIST_UNIFORM, 8, 16, 9, WS_ORDER_NUMBER); |
257 | for (i = 1; i <= nLineitems; i++) { |
258 | mk_detail(info_arr, 1); |
259 | } |
260 | |
261 | /** |
262 | * and finally return 1 since we have already printed the rows |
263 | */ |
264 | return 0; |
265 | } |
266 | |
267 | /* |
268 | * Routine: |
269 | * Purpose: |
270 | * Algorithm: |
271 | * Data Structures: |
272 | * |
273 | * Params: |
274 | * Returns: |
275 | * Called By: |
276 | * Calls: |
277 | * Assumptions: |
278 | * Side Effects: |
279 | * TODO: None |
280 | */ |
281 | int vld_web_sales(int nTable, ds_key_t kRow, int *Permutation) { |
282 | int nLineitem, nMaxLineitem, i; |
283 | |
284 | row_skip(nTable, kRow - 1); |
285 | row_skip(WEB_RETURNS, (kRow - 1)); |
286 | jDate = skipDays(WEB_SALES, &kNewDateIndex); |
287 | mk_master(NULL, kRow); |
288 | genrand_integer(&nMaxLineitem, DIST_UNIFORM, 8, 16, 9, WS_ORDER_NUMBER); |
289 | genrand_integer(&nLineitem, DIST_UNIFORM, 1, nMaxLineitem, 0, WS_PRICING_QUANTITY); |
290 | for (i = 1; i < nLineitem; i++) { |
291 | mk_detail(NULL, 0); |
292 | } |
293 | mk_detail(NULL, 1); |
294 | |
295 | return (0); |
296 | } |
297 | |