summaryrefslogtreecommitdiff
path: root/innobase/btr/ts/tscli.c
diff options
context:
space:
mode:
Diffstat (limited to 'innobase/btr/ts/tscli.c')
-rw-r--r--innobase/btr/ts/tscli.c3380
1 files changed, 3380 insertions, 0 deletions
diff --git a/innobase/btr/ts/tscli.c b/innobase/btr/ts/tscli.c
new file mode 100644
index 00000000000..6c42a83cdbe
--- /dev/null
+++ b/innobase/btr/ts/tscli.c
@@ -0,0 +1,3380 @@
+/************************************************************************
+Tests for the client, TPC-C, and TPC-D Query 5
+
+(c) 1996-1998 Innobase Oy
+
+Created 2/16/1996 Heikki Tuuri
+*************************************************************************/
+
+#include "univ.i"
+#include "ib_odbc.h"
+#include "mem0mem.h"
+#include "sync0sync.h"
+#include "os0thread.h"
+#include "os0proc.h"
+#include "os0sync.h"
+#include "srv0srv.h"
+
+ulint n_exited = 0;
+
+/* Disk wait simulation array */
+typedef struct srv_sim_disk_struct srv_sim_disk_t;
+struct srv_sim_disk_struct{
+ os_event_t event; /* OS event to wait */
+ bool event_set;/* TRUE if the event is in the set state */
+ bool empty; /* TRUE if this cell not reserved */
+};
+
+#define SRV_N_SIM_DISK_ARRAY 150
+
+srv_sim_disk_t srv_sim_disk[SRV_N_SIM_DISK_ARRAY];
+
+/* Random counter used in disk wait simulation */
+ulint srv_disk_rnd = 982364761;
+ulint srv_disk_n_active_threads = 0;
+
+char cli_srv_endpoint_name[100];
+char cli_user_name[100];
+
+ulint n_warehouses = ULINT_MAX;
+ulint n_customers_d = ULINT_MAX;
+bool is_tpc_d = FALSE;
+ulint n_rounds = ULINT_MAX;
+ulint n_users = ULINT_MAX;
+ulint startdate = 0;
+ulint enddate = 0;
+bool own_warehouse = FALSE;
+
+ulint mem_pool_size = ULINT_MAX;
+
+/*********************************************************************
+Test for TPC-C. */
+
+ulint
+test_init(
+/*======*/
+ void* arg)
+{
+ HENV env;
+ HDBC conn;
+ RETCODE ret;
+ HSTMT stat;
+ HSTMT create_query;
+ HSTMT populate_query;
+ char* str;
+ char* str1;
+ char* str2;
+ char* str3;
+ char* str4;
+ char* str5;
+ char* str6;
+ char* create_str;
+ char* populate_str;
+ char* commit_str;
+ char* new_order_str;
+ char* payment_str;
+ char* order_status_str;
+ char* delivery_str;
+ char* stock_level_str;
+ char* consistency_str;
+ char* query_5_str;
+ char* print_str;
+ char* lock_wait_str;
+ char* join_test_str;
+ char* test_errors_str;
+ char* test_group_commit_str;
+ char* test_single_row_select_str;
+ char* rollback_str;
+ char* ibuf_test_str;
+ SDWORD n_warehouses_buf;
+ SDWORD n_warehouses_len;
+ SDWORD n_customers_d_buf;
+ SDWORD n_customers_d_len;
+
+ UT_NOT_USED(arg);
+
+ /*------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE CREATE_TABLES () IS"
+" BEGIN"
+" CREATE TABLE WAREHOUSE (W_ID CHAR, W_NAME CHAR,"
+" W_STREET_1 CHAR, W_STREET_2 CHAR,"
+" W_CITY CHAR,"
+" W_STATE CHAR, W_ZIP CHAR,"
+" W_TAX INT,"
+" W_YTD_HIGH INT,"
+" W_YTD INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX W_IND ON WAREHOUSE (W_ID);"
+""
+" CREATE TABLE DISTRICT (D_ID CHAR, D_W_ID CHAR,"
+" D_NAME CHAR,"
+" D_STREET_1 CHAR, D_STREET_2 CHAR,"
+" D_CITY CHAR,"
+" D_STATE CHAR, D_ZIP CHAR,"
+" D_TAX INT,"
+" D_YTD_HIGH INT,"
+" D_YTD INT,"
+" D_NEXT_O_ID INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX D_IND ON DISTRICT (D_W_ID, D_ID);"
+""
+" CREATE TABLE CUSTOMER (C_ID CHAR, C_D_ID CHAR, C_W_ID CHAR,"
+" C_FIRST CHAR, C_MIDDLE CHAR,"
+" C_LAST CHAR,"
+" C_STREET_1 CHAR, C_STREET_2 CHAR,"
+" C_CITY CHAR,"
+" C_STATE CHAR, C_ZIP CHAR,"
+" C_PHONE CHAR,"
+" C_SINCE_TIME INT,"
+" C_SINCE INT,"
+" C_CREDIT CHAR,"
+" C_CREDIT_LIM_HIGH INT,"
+" C_CREDIT_LIM INT,"
+" C_DISCOUNT INT,"
+" C_BALANCE_HIGH INT,"
+" C_BALANCE INT,"
+" C_YTD_PAYMENT_HIGH INT,"
+" C_YTD_PAYMENT INT,"
+" C_PAYMENT_CNT INT,"
+" C_DELIVERY_CNT INT,"
+" C_DATA CHAR) /*DOES_NOT_FIT_IN_MEMORY*/;"
+""
+" CREATE UNIQUE CLUSTERED INDEX C_IND ON CUSTOMER (C_W_ID, C_D_ID,"
+" C_ID);"
+""
+" CREATE INDEX C_LAST_IND ON CUSTOMER (C_W_ID, C_D_ID, C_LAST,"
+" C_FIRST);"
+""
+" CREATE TABLE HISTORY (H_C_ID CHAR, H_C_D_ID CHAR, H_C_W_ID CHAR,"
+" H_D_ID CHAR, H_W_ID CHAR,"
+" H_DATE INT,"
+" H_AMOUNT INT,"
+" H_DATA CHAR);"
+""
+" CREATE CLUSTERED INDEX H_IND ON HISTORY (H_W_ID);"
+""
+" CREATE TABLE NEW_ORDER (NO_O_ID INT,"
+" NO_D_ID CHAR,"
+" NO_W_ID CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX NO_IND ON NEW_ORDER (NO_W_ID, NO_D_ID,"
+" NO_O_ID);"
+ ;
+
+ str2 =
+
+" CREATE TABLE ORDERS (O_ID INT, O_D_ID CHAR, O_W_ID CHAR,"
+" O_C_ID CHAR,"
+" O_ENTRY_D INT,"
+" O_CARRIER_ID INT,"
+" O_OL_CNT INT,"
+" O_ALL_LOCAL CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX O_IND ON ORDERS (O_W_ID, O_D_ID,"
+" O_ID);"
+" CREATE INDEX O_C_IND ON ORDERS (O_W_ID, O_D_ID, O_C_ID);"
+""
+" CREATE TABLE ORDER_LINE (OL_O_ID INT, OL_D_ID CHAR, OL_W_ID CHAR,"
+" OL_NUMBER CHAR,"
+" OL_I_ID CHAR,"
+" OL_SUPPLY_W_ID CHAR,"
+" OL_DELIVERY_D INT,"
+" OL_QUANTITY INT,"
+" OL_AMOUNT INT,"
+" OL_DIST_INFO CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX OL_IND ON ORDER_LINE"
+" (OL_W_ID, OL_D_ID, OL_O_ID, OL_NUMBER);"
+""
+" CREATE TABLE ITEM (I_ID CHAR, I_IM_ID CHAR, I_NAME CHAR,"
+" I_PRICE INT,"
+" I_DATA CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX I_IND ON ITEM (I_ID);"
+""
+" CREATE TABLE STOCK (S_I_ID CHAR,"
+" S_W_ID CHAR,"
+" S_QUANTITY INT,"
+" S_DIST_01 CHAR,"
+" S_DIST_02 CHAR,"
+" S_DIST_03 CHAR,"
+" S_DIST_04 CHAR,"
+" S_DIST_05 CHAR,"
+" S_DIST_06 CHAR,"
+" S_DIST_07 CHAR,"
+" S_DIST_08 CHAR,"
+" S_DIST_09 CHAR,"
+" S_DIST_10 CHAR,"
+" S_YTD INT,"
+" S_ORDER_CNT INT,"
+" S_REMOTE_CNT INT,"
+" S_DATA CHAR) /*DOES_NOT_FIT_IN_MEMORY*/;"
+""
+" CREATE UNIQUE CLUSTERED INDEX S_IND ON STOCK (S_W_ID, S_I_ID);"
+""
+""
+" CREATE TABLE REGION (R_REGIONKEY INT, R_NAME CHAR, R_COMMENT CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX R_IND ON REGION (R_REGIONKEY);"
+""
+" CREATE TABLE NATION (N_NATIONKEY INT, N_NAME CHAR, N_REGIONKEY INT,"
+" N_COMMENT CHAR);"
+" CREATE UNIQUE CLUSTERED INDEX N_IND ON NATION (N_NATIONKEY);"
+""
+" CREATE TABLE NATION_2 (N2_NATIONKEY INT, N2_NAME CHAR,"
+" N2_REGIONKEY INT, N2_COMMENT CHAR);"
+" CREATE UNIQUE CLUSTERED INDEX N2_IND ON NATION_2 (N2_NAME);"
+""
+" CREATE TABLE SUPPLIER (S_SUPPKEY INT, S_NAME CHAR, S_ADDRESS CHAR,"
+" S_NATIONKEY INT, S_PHONE CHAR,"
+" S_ACCTBAL INT, S_COMMENT CHAR);"
+" CREATE UNIQUE CLUSTERED INDEX SU_IND ON SUPPLIER (S_SUPPKEY);"
+""
+" CREATE TABLE CUSTOMER_D (C_CUSTKEY INT, C_NAME CHAR, C_ADDRESS CHAR,"
+" C_NATIONKEY INT, C_PHONE CHAR,"
+" C_ACCTBAL INT, C_MKTSEGMENT CHAR,"
+" C_COMMENT CHAR);"
+" CREATE UNIQUE CLUSTERED INDEX CU_IND ON CUSTOMER_D (C_CUSTKEY);"
+""
+" CREATE TABLE ORDERS_D (O_ORDERKEY INT, O_CUSTKEY INT,"
+" O_ORDERSTATUS CHAR, O_TOTALPRICE INT,"
+" O_ORDERDATE INT,"
+" O_ORDERPRIORITY CHAR,"
+" O_CLERK CHAR, O_SHIPPRIORITY INT,"
+" O_COMMENT CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX OR_IND ON ORDERS_D (O_ORDERKEY);"
+""
+" CREATE INDEX OR_D_IND ON ORDERS_D (O_ORDERDATE, O_ORDERKEY,"
+" O_CUSTKEY);"
+""
+" CREATE TABLE LINEITEM (L_ORDERKEY INT, L_PARTKEY INT, L_SUPPKEY INT,"
+" L_LINENUMBER INT, L_QUANTITY INT,"
+" L_EXTENDEDPRICE INT,"
+" L_DISCOUNT INT, L_TAX INT,"
+" L_RETURNFLAG CHAR,"
+" L_LINESTATUS CHAR,"
+" L_SHIPDATE INT, L_COMMITDATE INT,"
+" L_RECEIPTDATE INT,"
+" L_SHIPINSTRUCT CHAR,"
+" L_SHIPMODE CHAR, L_COMMENT CHAR);"
+""
+" CREATE UNIQUE CLUSTERED INDEX L_IND ON LINEITEM (L_ORDERKEY,"
+" L_LINENUMBER);"
+""
+" CREATE TABLE ACCOUNTA (A_NUM INT, A_BAL INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX ACCOUNTA_IND ON ACCOUNTA (A_NUM);"
+""
+" CREATE TABLE TELLERA (T_NUM INT, T_BAL INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX TELLERA_IND ON TELLERA (T_NUM);"
+""
+" CREATE TABLE BRANCHA (B_NUM INT, B_BAL INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX BRANCHA_IND ON BRANCHA (B_NUM);"
+""
+" CREATE TABLE HISTORYA (H_NUM INT, H_TEXT CHAR);"
+""
+" CREATE CLUSTERED INDEX HISTORYA_IND ON HISTORYA (H_NUM);"
+""
+" CREATE TABLE JTEST1 (JT1_A INT, JT1_B INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX JT_IND1 ON JTEST1 (JT1_A);"
+""
+" CREATE TABLE JTEST2 (JT2_A INT, JT2_B INT);"
+""
+" CREATE UNIQUE CLUSTERED INDEX JT_IND2 ON JTEST2 (JT2_A);"
+""
+" CREATE TABLE IBUF_TEST (IB_A INT, IB_B CHAR) DOES_NOT_FIT_IN_MEMORY;"
+""
+" CREATE UNIQUE CLUSTERED INDEX IBUF_IND ON IBUF_TEST (IB_A);"
+" END;"
+ ;
+
+ create_str = ut_str_catenate(str1, str2);
+ /*-----------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE POPULATE_TABLES (n_warehouses IN INT, n_customers_d"
+" IN INT) IS"
+""
+" i INT;"
+" j INT;"
+" k INT;"
+" t INT;"
+" string CHAR;"
+" rnd1 INT;"
+" rnd2 INT;"
+" rnd INT;"
+" n_items INT;"
+" n_districts INT;"
+" n_customers INT;"
+""
+" BEGIN"
+""
+"/**********************************************************/"
+" PRINTF('Starting Mikko-test');"
+""
+" FOR i IN 1 .. 5 LOOP"
+" INSERT INTO IBUF_TEST VALUES (i, 'Mikko');"
+" END LOOP;"
+""
+" /* PRINTF('Printing rows from Mikko-test:');"
+""
+" ROW_PRINTF SELECT * FROM IBUF_TEST; */"
+""
+" SELECT SUM(IB_A) INTO t FROM IBUF_TEST;"
+""
+" PRINTF('Sum of 1 to ', i, ' is ', t);"
+" ASSERT(t = (i * (i + 1)) / 2);"
+""
+" ROLLBACK WORK;"
+""
+" PRINTF('Printing rows from Mikko-test after rollback:');"
+""
+" ROW_PRINTF SELECT * FROM IBUF_TEST;"
+""
+"/**********************************************************/"
+" FOR i IN 0 .. 100 LOOP"
+" INSERT INTO ACCOUNTA VALUES (i, i);"
+" INSERT INTO TELLERA VALUES (i, i);"
+" INSERT INTO BRANCHA VALUES (i, i);"
+" INSERT INTO HISTORYA VALUES (i, '12345678901234567890');"
+" END LOOP;"
+""
+" COMMIT WORK;"
+"/**********************************************************/"
+"/* PRINTF('Populating ibuf test tables');"
+" FOR i IN 1 .. 1000 LOOP"
+" INSERT INTO IBUF_TEST VALUES (i, RND_STR(RND(1, 2000)));"
+" END LOOP;"
+" PRINTF('Ibuf test tables populated');"
+" COMMIT WORK; */"
+""
+" n_items := 200;"
+" n_districts := 10;"
+" n_customers := 20;"
+""
+" PRINTF('Starting to populate ITEMs');"
+""
+" FOR i IN 1 .. n_items LOOP"
+" rnd1 := RND(26, 50);"
+" string := RND_STR(rnd1);"
+""
+" IF (RND(0, 99) < 10) THEN"
+" rnd2 := RND(0, rnd1 - 8);"
+" REPLSTR(string, 'ORIGINAL', rnd2, 8);"
+" END IF;"
+""
+" INSERT INTO ITEM VALUES (TO_BINARY(i, 3),"
+" TO_BINARY(RND(1, 10000), 3),"
+" RND_STR(RND(14, 24)),"
+" RND(100, 10000),"
+" string);"
+" END LOOP;"
+" COMMIT WORK;"
+""
+" FOR i IN 1 .. n_warehouses LOOP"
+" COMMIT WORK;"
+" PRINTF('Starting to populate warehouse number ', i);"
+" INSERT INTO WAREHOUSE VALUES (TO_BINARY(i, 2),"
+" RND_STR(RND(6, 10)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(2),"
+" CONCAT(SUBSTR(TO_CHAR(RND(0, 9999)),"
+" 6, 4),"
+" '11111'),"
+" RND(0, 2000),"
+" 0,"
+" 0);"
+" FOR j IN 1 .. n_items LOOP"
+""
+" rnd1 := RND(26, 50);"
+" string := RND_STR(rnd1);"
+""
+" IF (RND(0, 99) < 10) THEN"
+" rnd2 := RND(0, rnd1 - 8);"
+" REPLSTR(string, 'ORIGINAL', rnd2, 8);"
+" END IF; "
+""
+" INSERT INTO STOCK VALUES (TO_BINARY(j, 3),"
+" TO_BINARY(i, 2),"
+" 91,"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" RND_STR(24),"
+" 0, 0, 0,"
+" string);"
+" END LOOP;"
+ ;
+
+ str2 =
+" FOR j IN 1 .. n_districts LOOP"
+""
+" /* PRINTF('Starting to populate district number ', j); */"
+" INSERT INTO DISTRICT VALUES (TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" RND_STR(RND(6, 10)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(2),"
+" CONCAT(SUBSTR("
+" TO_CHAR(RND(0, 9999)),"
+" 6, 4),"
+" '11111'),"
+" RND(0, 2000),"
+" 0,"
+" 0,"
+" 3001);"
+""
+" FOR k IN 1 .. n_customers LOOP"
+""
+" string := 'GC';"
+""
+" IF (RND(0, 99) < 10) THEN"
+" string := 'BC';"
+" END IF;"
+" "
+" INSERT INTO CUSTOMER VALUES ("
+" TO_BINARY(k, 3),"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" RND_STR(RND(8, 16)),"
+" 'OE',"
+" CONCAT('NAME',"
+" TO_CHAR(k / 3)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(RND(10, 20)),"
+" RND_STR(2),"
+" CONCAT(SUBSTR("
+" TO_CHAR(RND(0, 9999)),"
+" 6, 4),"
+" '11111'),"
+" RND_STR(16),"
+" SYSDATE(), 0,"
+" string,"
+" 0, 5000000,"
+" RND(0, 5000),"
+" 0, 0, 0, 0, 0, 0,"
+" RND_STR(RND(300, 500)));"
+ ;
+
+ str3 =
+" INSERT INTO HISTORY VALUES ("
+" TO_BINARY(k, 3),"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" SYSDATE(),"
+" 1000,"
+" RND_STR(RND(12, 24)));"
+""
+" rnd1 := RND(5, 15);"
+""
+" INSERT INTO ORDERS VALUES ("
+" k,"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" TO_BINARY(k, 3),"
+" SYSDATE(),"
+" RND(1, 10),"
+" rnd1,"
+" '1');"
+""
+" FOR t IN 1 .. rnd1 LOOP"
+" INSERT INTO ORDER_LINE VALUES ("
+" k,"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2),"
+" TO_BINARY(t, 1),"
+" TO_BINARY("
+" RND(1, n_items),"
+" 3),"
+" TO_BINARY(i, 2),"
+" NULL,"
+" 91,"
+" RND(0, 9999),"
+" RND_STR(24));"
+" END LOOP;"
+" END LOOP;"
+" "
+" FOR k IN 1 /* + (2 * n_customers) / 3 */"
+" .. n_customers LOOP"
+" "
+" INSERT INTO NEW_ORDER VALUES ("
+" k,"
+" TO_BINARY(j + 47, 1),"
+" TO_BINARY(i, 2));"
+" END LOOP;"
+" END LOOP;"
+" END LOOP;"
+""
+" COMMIT WORK;"
+""
+" PRINTF('Populating TPC-D tables');"
+""
+" FOR i IN 0 .. 4 LOOP"
+" /* We set the last columns to a long character string, to"
+" reduce latch contention on region and nation database pages."
+" A similar effect could be achieved by setting the page"
+" fillfactor in these tables low. */"
+""
+" INSERT INTO REGION VALUES (i, CONCAT('Region', TO_CHAR(i),"
+" ' '),"
+" RND_STR(1500 + RND(1, 152)));"
+" FOR j IN i * 5 .. i * 5 + 4 LOOP"
+" INSERT INTO NATION VALUES (j,"
+" CONCAT('Nation', TO_CHAR(j),"
+" ' '),"
+" i, RND_STR(1500 + RND(1, 152)));"
+" INSERT INTO NATION_2 VALUES (j,"
+" CONCAT('Nation', TO_CHAR(j),"
+" ' '),"
+" i, RND_STR(1500 + RND(1, 152)));"
+" END LOOP;"
+" END LOOP;"
+""
+" COMMIT WORK;"
+""
+" FOR i IN 0 .. n_customers_d / 15 LOOP"
+" INSERT INTO SUPPLIER VALUES (i,"
+" CONCAT('Supplier', TO_CHAR(i)),"
+" RND_STR(RND(20, 30)),"
+" RND(0, 24),"
+" RND_STR(15),"
+" RND(1, 1000),"
+" RND_STR(RND(40, 80)));"
+" END LOOP;"
+""
+" COMMIT WORK;"
+""
+" FOR i IN 0 .. n_customers_d - 1 LOOP"
+" IF ((i / 100) * 100 = i) THEN"
+" COMMIT WORK;"
+" PRINTF('Populating customer ', i);"
+" END IF;"
+""
+" INSERT INTO CUSTOMER_D VALUES (i,"
+" CONCAT('Customer', TO_CHAR(i)),"
+" RND_STR(RND(20, 30)),"
+" RND(0, 24),"
+" RND_STR(15),"
+" RND(1, 1000),"
+" RND_STR(10),"
+" RND_STR(RND(50, 100)));"
+""
+" FOR j IN i * 10 .. i * 10 + 9 LOOP"
+""
+" rnd := (j * 2400) / (10 * n_customers_d);"
+""
+" INSERT INTO ORDERS_D VALUES (j,"
+" 3 * RND(0, (n_customers_d / 3) - 1)"
+" + RND(1, 2),"
+" 'F', 1000,"
+" rnd,"
+" RND_STR(10),"
+" CONCAT('Clerk', TO_CHAR(RND(0, 1000))),"
+" 0, RND_STR(RND(3, 7)));"
+""
+" FOR k IN 0 .. RND(0, 6) LOOP"
+" INSERT INTO LINEITEM VALUES (j,"
+" RND(1, 1000),"
+" RND(0, n_customers_d / 15),"
+" k,"
+" RND(1, 50),"
+" 100,"
+" 5,"
+" RND(0, 8),"
+" 'N',"
+" 'F',"
+" rnd + RND(1, 100),"
+" rnd + RND(1, 100),"
+" rnd + RND(1, 100),"
+" RND_STR(1),"
+" RND_STR(1),"
+" RND_STR(RND(1, 3)));"
+" END LOOP;"
+" END LOOP;"
+""
+" END LOOP;"
+""
+" COMMIT WORK;"
+" PRINTF('TPC-D tables populated');"
+""
+" PRINTF('Populating join test tables');"
+" FOR i IN 1 .. 1 LOOP"
+" INSERT INTO JTEST1 VALUES (i, i);"
+" INSERT INTO JTEST2 VALUES (i, i);"
+" END LOOP;"
+" PRINTF('Join test tables populated');"
+""
+" COMMIT WORK;"
+" END;"
+ ;
+
+ str4 = ut_str_catenate(str1, str2);
+ populate_str = ut_str_catenate(str4, str3);
+
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE PRINT_TABLES () IS"
+" i INT;"
+" BEGIN"
+""
+" /* PRINTF('Printing ITEM table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM ITEM;"
+""
+" PRINTF('Printing WAREHOUSE table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM WAREHOUSE;"
+""
+" PRINTF('Printing STOCK table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM STOCK;"
+""
+" PRINTF('Printing DISTRICT table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM DISTRICT;"
+""
+" PRINTF('Printing CUSTOMER table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM CUSTOMER;"
+""
+" PRINTF('Printing HISTORY table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM HISTORY;"
+""
+" PRINTF('Printing ORDERS table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM ORDERS;"
+""
+" PRINTF('Printing ORDER_LINE table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM ORDER_LINE"
+" WHERE OL_O_ID >= 3000; */"
+""
+" PRINTF('Printing NEW_ORDER table:');"
+""
+" ROW_PRINTF"
+" SELECT *"
+" FROM NEW_ORDER;"
+""
+" COMMIT WORK;"
+" END;"
+ ;
+
+ print_str = str;
+ /*-----------------------------------------------------------*/
+ commit_str =
+
+" PROCEDURE COMMIT_TEST () IS"
+" "
+" BEGIN"
+" COMMIT WORK;"
+" END;"
+ ;
+
+ /*-----------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE NEW_ORDER (c_w_id IN CHAR,"
+" c_d_id IN CHAR,"
+" c_id IN CHAR,"
+" ol_supply_w_ids IN CHAR,"
+" ol_i_ids IN CHAR,"
+" ol_quantities IN CHAR,"
+" c_last OUT CHAR,"
+" c_credit OUT CHAR,"
+" c_discount OUT INT,"
+" w_tax OUT INT,"
+" d_tax OUT INT,"
+" o_ol_count OUT INT,"
+" o_id OUT INT,"
+" o_entry_d OUT INT,"
+" total OUT INT,"
+" i_names OUT CHAR,"
+" s_quantities OUT CHAR,"
+" bg OUT CHAR,"
+" i_prices OUT CHAR,"
+" ol_amounts OUT CHAR) IS"
+""
+" i INT;"
+" j INT;"
+" o_all_local CHAR;"
+" i_price INT;"
+" i_name CHAR;"
+" i_data CHAR;"
+" s_quantity INT;"
+" s_data CHAR;"
+" s_dist_01 CHAR;"
+" s_dist_02 CHAR;"
+" s_dist_03 CHAR;"
+" s_dist_04 CHAR;"
+" s_dist_05 CHAR;"
+" s_dist_06 CHAR;"
+" s_dist_07 CHAR;"
+" s_dist_08 CHAR;"
+" s_dist_09 CHAR;"
+" s_dist_10 CHAR;"
+" ol_i_id CHAR;"
+" ol_quantity INT;"
+" ol_amount INT;"
+" ol_supply_w_id CHAR;"
+" ol_dist_info CHAR;"
+""
+" DECLARE CURSOR district_cursor IS"
+" SELECT D_NEXT_O_ID, D_TAX"
+" FROM DISTRICT"
+" WHERE D_ID = c_d_id AND D_W_ID = c_w_id"
+" FOR UPDATE;"
+""
+" DECLARE CURSOR stock_cursor IS"
+" SELECT S_QUANTITY, S_DATA,"
+" S_DIST_01, S_DIST_02, S_DIST_03, S_DIST_04,"
+" S_DIST_05, S_DIST_06, S_DIST_07, S_DIST_08,"
+" S_DIST_09, S_DIST_10"
+" FROM STOCK"
+" WHERE S_W_ID = ol_supply_w_id AND S_I_ID = ol_i_id"
+" FOR UPDATE;"
+ ;
+ str2 =
+
+" BEGIN"
+" FOR j IN 1 .. 1 LOOP"
+""
+" /* PRINTF('Warehouse ', BINARY_TO_NUMBER(c_w_id)); */"
+" o_all_local := '1';"
+" i_names := '12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "12345678901234567890123456789012345678901234567890"
+ "1234567890';"
+" s_quantities := '12345678901234567890123456789012345678901234567890"
+ "1234567890';"
+" i_prices := '12345678901234567890123456789012345678901234567890"
+ "1234567890';"
+" ol_amounts := '12345678901234567890123456789012345678901234567890"
+ "1234567890';"
+" bg := 'GGGGGGGGGGGGGGG';"
+" total := 0;"
+""
+" SELECT C_DISCOUNT, C_LAST, C_CREDIT INTO c_discount, c_last, c_credit"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;"
+""
+" OPEN district_cursor;"
+""
+" FETCH district_cursor INTO o_id, d_tax;"
+""
+" UPDATE DISTRICT SET D_NEXT_O_ID = o_id + 1"
+" WHERE CURRENT OF district_cursor;"
+""
+" CLOSE district_cursor;"
+""
+""
+ ;
+ str3 =
+
+" o_ol_count := LENGTH(ol_quantities);"
+""
+" /* PRINTF('C-WAREHOUSE id ', BINARY_TO_NUMBER(c_w_id),"
+" ' C-district id ', c_d_id,"
+" ' order id ', o_id, ' linecount ', o_ol_count); */"
+""
+" FOR i IN 0 .. (o_ol_count - 1) LOOP"
+""
+" ol_i_id := SUBSTR(ol_i_ids, 3 * i, 3);"
+" ol_supply_w_id := SUBSTR(ol_supply_w_ids, 2 * i, 2);"
+" ol_quantity := BINARY_TO_NUMBER(SUBSTR(ol_quantities, i, 1));"
+""
+" /* PRINTF('ol_i_id ', BINARY_TO_NUMBER(ol_i_id),"
+" ' ol_supply_w_id ', BINARY_TO_NUMBER(ol_supply_w_id),"
+" ' ol_quantity ', ol_quantity); */"
+""
+" SELECT I_PRICE, I_NAME, I_DATA INTO i_price, i_name, i_data"
+" FROM ITEM"
+" WHERE I_ID = ol_i_id"
+" CONSISTENT READ;"
+""
+" IF (SQL % NOTFOUND) THEN"
+" /* PRINTF('Rolling back; item not found: ',"
+" BINARY_TO_NUMBER(ol_i_id)); */"
+" ROLLBACK WORK;"
+" o_ol_count := 0;"
+""
+" RETURN;"
+" END IF;"
+""
+" OPEN stock_cursor;"
+""
+" FETCH stock_cursor INTO s_quantity, s_data,"
+" s_dist_01, s_dist_02, s_dist_03,"
+" s_dist_04, s_dist_05, s_dist_06,"
+" s_dist_07, s_dist_08, s_dist_09,"
+" s_dist_10;"
+""
+" /* PRINTF('Stock quantity ', s_quantity); */"
+""
+" IF (s_quantity >= ol_quantity + 10) THEN"
+" s_quantity := s_quantity - ol_quantity;"
+" ELSE"
+" s_quantity := (s_quantity + 91) - ol_quantity;"
+" END IF;"
+""
+" UPDATE STOCK SET S_QUANTITY = s_quantity,"
+" S_YTD = S_YTD + ol_quantity,"
+" S_ORDER_CNT = S_ORDER_CNT + 1"
+ " WHERE CURRENT OF stock_cursor;"
+""
+" IF (ol_supply_w_id <> c_w_id) THEN"
+""
+" o_all_local := '0';"
+" PRINTF('Remote order ',"
+" BINARY_TO_NUMBER(ol_supply_w_id), ' ',"
+" BINARY_TO_NUMBER(c_w_id));"
+""
+" UPDATE STOCK SET S_REMOTE_CNT = S_REMOTE_CNT + 1"
+" WHERE CURRENT OF stock_cursor;"
+" END IF;"
+""
+" CLOSE stock_cursor;"
+""
+" IF ((INSTR(i_data, 'ORIGINAL') > 0)"
+" OR (INSTR(s_data, 'ORIGINAL') > 0)) THEN"
+" REPLSTR(bg, 'B', i, 1);"
+" END IF;"
+""
+" ol_amount := ol_quantity * i_price;"
+""
+" total := total + ol_amount;"
+ ;
+ str4 =
+" IF (c_d_id = '0') THEN"
+" ol_dist_info := s_dist_01;"
+" ELSIF (c_d_id = '1') THEN"
+" ol_dist_info := s_dist_02;"
+" ELSIF (c_d_id = '2') THEN"
+" ol_dist_info := s_dist_03;"
+" ELSIF (c_d_id = '3') THEN"
+" ol_dist_info := s_dist_04;"
+" ELSIF (c_d_id = '4') THEN"
+" ol_dist_info := s_dist_05;"
+" ELSIF (c_d_id = '5') THEN"
+" ol_dist_info := s_dist_06;"
+" ELSIF (c_d_id = '6') THEN"
+" ol_dist_info := s_dist_07;"
+" ELSIF (c_d_id = '7') THEN"
+" ol_dist_info := s_dist_08;"
+" ELSIF (c_d_id = '8') THEN"
+" ol_dist_info := s_dist_09;"
+" ELSIF (c_d_id = '9') THEN"
+" ol_dist_info := s_dist_10;"
+" END IF;"
+""
+" INSERT INTO ORDER_LINE VALUES (o_id, c_d_id, c_w_id,"
+" TO_BINARY(i + 1, 1), ol_i_id,"
+" ol_supply_w_id, NULL, ol_quantity,"
+" ol_amount, ol_dist_info);"
+""
+" REPLSTR(i_names, i_name, i * 24, LENGTH(i_name));"
+" REPLSTR(s_quantities, TO_BINARY(s_quantity, 4), i * 4, 4);"
+" REPLSTR(i_prices, TO_BINARY(i_price, 4), i * 4, 4);"
+" REPLSTR(ol_amounts, TO_BINARY(ol_amount, 4), i * 4, 4);"
+""
+" /* PRINTF('i_name ', i_name, ' s_quantity ', s_quantity,"
+" ' i_price ', i_price, ' ol_amount ', ol_amount); */"
+" END LOOP;"
+""
+" SELECT W_TAX INTO w_tax"
+" FROM WAREHOUSE"
+" WHERE W_ID = c_w_id;"
+""
+" total := (((total * (10000 + w_tax + d_tax)) / 10000)"
+" * (10000 - c_discount)) / 10000;"
+""
+" o_entry_d := SYSDATE();"
+""
+" INSERT INTO ORDERS VALUES (o_id, c_d_id, c_w_id, c_id, o_entry_d,"
+" NULL, o_ol_count, o_all_local);"
+" INSERT INTO NEW_ORDER VALUES (o_id, c_d_id, c_w_id);"
+""
+" /* PRINTF('Inserted order lines:');"
+" ROW_PRINTF"
+" SELECT * FROM ORDER_LINE WHERE OL_O_ID = o_id AND"
+" OL_D_ID = c_d_id"
+" AND OL_W_ID = c_w_id; */"
+" COMMIT WORK;"
+" END LOOP;"
+" END;"
+ ;
+
+ str5 = ut_str_catenate(str1, str2);
+ str6 = ut_str_catenate(str3, str4);
+
+ new_order_str = ut_str_catenate(str5, str6);
+
+ /*-----------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE PAYMENT (c_w_id IN CHAR) IS"
+""
+" i INT;"
+" n_items INT;"
+" n_warehouses INT;"
+" n_districts INT;"
+" n_customers INT;"
+" w_id CHAR;"
+" w_street_1 CHAR;"
+" w_street_2 CHAR;"
+" w_city CHAR;"
+" w_state CHAR;"
+" w_zip CHAR;"
+" w_name CHAR;"
+" d_id CHAR;"
+" d_street_1 CHAR;"
+" d_street_2 CHAR;"
+" d_city CHAR;"
+" d_state CHAR;"
+" d_zip CHAR;"
+" d_name CHAR;"
+" c_d_id CHAR;"
+" c_street_1 CHAR;"
+" c_street_2 CHAR;"
+" c_city CHAR;"
+" c_state CHAR;"
+" c_zip CHAR;"
+" c_id CHAR;"
+" c_last CHAR;"
+" c_first CHAR;"
+" c_middle CHAR;"
+" c_phone CHAR;"
+" c_credit CHAR;"
+" c_credit_lim INT;"
+" c_discount INT;"
+" c_balance INT;"
+" c_since INT;"
+" c_data CHAR;"
+" byname INT;"
+" namecnt INT;"
+" amount INT;"
+" h_data CHAR;"
+" h_date INT;"
+" c_more_data CHAR;"
+" more_len INT;"
+" data_len INT;"
+""
+" DECLARE CURSOR warehouse_cursor IS"
+" SELECT W_STREET_1, W_STREET_2, W_CITY, W_STATE, W_ZIP, W_NAME"
+" FROM WAREHOUSE"
+" WHERE W_ID = w_id"
+" FOR UPDATE;"
+""
+" DECLARE CURSOR district_cursor IS"
+" SELECT D_STREET_1, D_STREET_2, D_CITY, D_STATE, D_ZIP, D_NAME"
+" FROM DISTRICT"
+" WHERE D_W_ID = w_id AND D_ID = d_id"
+" FOR UPDATE;"
+""
+" DECLARE CURSOR customer_by_name_cursor IS"
+" SELECT C_ID"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_LAST = c_last"
+" ORDER BY C_FIRST ASC;"
+""
+" DECLARE CURSOR customer_cursor IS"
+" SELECT C_FIRST, C_MIDDLE, C_LAST, C_STREET_1, C_STREET_2,"
+" C_CITY, C_STATE, C_ZIP, C_PHONE, C_CREDIT,"
+" C_CREDIT_LIM, C_DISCOUNT, C_BALANCE,"
+" C_SINCE"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_ID = c_id"
+" FOR UPDATE;"
+ ;
+
+ str2 =
+
+" BEGIN"
+""
+" n_items := 200;"
+" n_warehouses := 1;"
+" n_districts := 10;"
+" n_customers := 20;"
+""
+" byname := RND(1, 100);"
+" amount := RND(1, 1000);"
+" h_date := SYSDATE();"
+" w_id := c_w_id;"
+" d_id := TO_BINARY(47 + RND(1, n_districts), 1);"
+" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);"
+""
+" IF (byname <= 60) THEN"
+" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));"
+""
+" SELECT COUNT(*) INTO namecnt"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_LAST = c_last;"
+" /* PRINTF('Payment trx: Customer name ', c_last,"
+" ' namecount ', namecnt); */"
+" OPEN customer_by_name_cursor;"
+""
+" FOR i IN 1 .. (namecnt + 1) / 2 LOOP"
+" FETCH customer_by_name_cursor INTO c_id;"
+" END LOOP;"
+" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */"
+" "
+" CLOSE customer_by_name_cursor;"
+" ELSE"
+" c_id := TO_BINARY(RND(1, n_customers), 3);"
+" END IF;"
+
+ ;
+ str3 =
+""
+" /* PRINTF('Payment for customer ', BINARY_TO_NUMBER(c_w_id), ' ',"
+" c_d_id, ' ', BINARY_TO_NUMBER(c_id)); */"
+" OPEN customer_cursor;"
+""
+" FETCH customer_cursor INTO c_first, c_middle, c_last, c_street_1,"
+" c_street_2, c_city, c_state, c_zip,"
+" c_phone, c_credit, c_credit_lim,"
+" c_discount, c_balance, c_since;"
+" c_balance := c_balance - amount;"
+""
+" OPEN district_cursor;"
+""
+" FETCH district_cursor INTO d_street_1, d_street_2, d_city, d_state,"
+" d_zip, d_name;"
+" UPDATE DISTRICT SET D_YTD = D_YTD + amount"
+" WHERE CURRENT OF district_cursor;"
+""
+" CLOSE district_cursor;"
+""
+" OPEN warehouse_cursor;"
+""
+" FETCH warehouse_cursor INTO w_street_1, w_street_2, w_city, w_state,"
+" w_zip, w_name;"
+" UPDATE WAREHOUSE SET W_YTD = W_YTD + amount"
+" WHERE CURRENT OF warehouse_cursor;"
+""
+" CLOSE warehouse_cursor;"
+""
+" h_data := CONCAT(w_name, ' ', d_name);"
+" "
+" IF (c_credit = 'BC') THEN"
+" /* PRINTF('Bad customer pays'); */"
+""
+" SELECT C_DATA INTO c_data"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_ID = c_id;"
+" c_more_data := CONCAT("
+" ' ', TO_CHAR(BINARY_TO_NUMBER(c_id)),"
+" ' ', c_d_id,"
+" ' ', TO_CHAR(BINARY_TO_NUMBER(c_w_id)),"
+" ' ', d_id,"
+" ' ', TO_CHAR(BINARY_TO_NUMBER(w_id)),"
+" TO_CHAR(amount),"
+" TO_CHAR(h_date),"
+" ' ', h_data);"
+""
+" more_len := LENGTH(c_more_data);"
+" data_len := LENGTH(c_data);"
+" "
+" IF (more_len + data_len > 500) THEN"
+" data_len := 500 - more_len;"
+" END IF;"
+" "
+" c_data := CONCAT(c_more_data, SUBSTR(c_data, 0, data_len));"
+" "
+" UPDATE CUSTOMER SET C_BALANCE = c_balance,"
+" C_PAYMENT_CNT = C_PAYMENT_CNT + 1,"
+" C_YTD_PAYMENT = C_YTD_PAYMENT + amount,"
+" C_DATA = c_data"
+" WHERE CURRENT OF customer_cursor;"
+" ELSE"
+" UPDATE CUSTOMER SET C_BALANCE = c_balance,"
+" C_PAYMENT_CNT = C_PAYMENT_CNT + 1,"
+" C_YTD_PAYMENT = C_YTD_PAYMENT + amount"
+" WHERE CURRENT OF customer_cursor;"
+" END IF;"
+""
+" CLOSE customer_cursor;"
+" "
+" INSERT INTO HISTORY VALUES (c_d_id, c_w_id, c_id, d_id, w_id,"
+" h_date, amount, h_data);"
+" COMMIT WORK;"
+""
+" END;"
+
+ ;
+
+ str4 = ut_str_catenate(str1, str2);
+ payment_str = ut_str_catenate(str4, str3);
+
+ /*-----------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE ORDER_STATUS (c_w_id IN CHAR) IS"
+""
+" i INT;"
+" n_items INT;"
+" n_warehouses INT;"
+" n_districts INT;"
+" n_customers INT;"
+" d_id CHAR;"
+" namecnt INT;"
+" c_d_id CHAR;"
+" c_id CHAR;"
+" c_last CHAR;"
+" c_first CHAR;"
+" c_middle CHAR;"
+" c_balance INT;"
+" byname INT;"
+" o_id INT;"
+" o_carrier_id CHAR;"
+" o_entry_d INT;"
+" ol_i_id CHAR;"
+" ol_supply_w_id CHAR;"
+" ol_quantity INT;"
+" ol_amount INT;"
+" ol_delivery_d INT;"
+""
+" DECLARE CURSOR orders_cursor IS"
+" SELECT O_ID, O_CARRIER_ID, O_ENTRY_D"
+" FROM ORDERS"
+" WHERE O_W_ID = c_w_id AND O_D_ID = c_d_id"
+" AND O_C_ID = c_id"
+" ORDER BY O_ID DESC;"
+""
+" DECLARE CURSOR order_line_cursor IS"
+" SELECT OL_I_ID, OL_SUPPLY_W_ID, OL_QUANTITY, OL_AMOUNT,"
+" OL_DELIVERY_D"
+" FROM ORDER_LINE"
+" WHERE OL_W_ID = c_w_id AND OL_D_ID = c_d_id"
+" AND OL_O_ID = o_id;"
+" DECLARE CURSOR customer_by_name_cursor IS"
+" SELECT C_ID"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_LAST = c_last"
+" ORDER BY C_FIRST ASC;"
+" BEGIN"
+""
+" n_items := 200;"
+" n_warehouses := 1;"
+" n_districts := 10;"
+" n_customers := 20;"
+""
+" byname := RND(1, 100);"
+""
+ ;
+
+ str2 =
+
+" IF (byname <= 60) THEN"
+" d_id := TO_BINARY(47 + RND(1, n_districts), 1); "
+""
+" c_d_id := d_id;"
+""
+" c_last := CONCAT('NAME', TO_CHAR(RND(1, n_customers) / 3));"
+""
+" SELECT COUNT(*) INTO namecnt"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id"
+" AND C_LAST = c_last;"
+" OPEN customer_by_name_cursor;"
+""
+" /* PRINTF('Order status trx: Customer name ', c_last,"
+" ' namecount ', namecnt); */"
+" FOR i IN 1 .. (namecnt + 1) / 2 LOOP"
+" FETCH customer_by_name_cursor INTO c_id;"
+" END LOOP;"
+" /* ASSERT(NOT (customer_by_name_cursor % NOTFOUND)); */"
+""
+" CLOSE customer_by_name_cursor;"
+" ELSE"
+" c_d_id := TO_BINARY(47 + RND(1, n_districts), 1);"
+" c_id := TO_BINARY(RND(1, n_customers), 3);"
+" END IF;"
+""
+" SELECT C_BALANCE, C_FIRST, C_MIDDLE, C_LAST INTO c_balance, c_first,"
+" c_middle, c_last"
+" FROM CUSTOMER"
+" WHERE C_W_ID = c_w_id AND C_D_ID = c_d_id AND C_ID = c_id;"
+""
+" OPEN orders_cursor;"
+""
+" FETCH orders_cursor INTO o_id, o_carrier_id, o_entry_d;"
+""
+" IF (orders_cursor % NOTFOUND) THEN"
+" PRINTF('Order status trx: customer has no order');"
+" CLOSE orders_cursor;"
+""
+" COMMIT WORK;"
+""
+" RETURN;"
+" END IF;"
+""
+" CLOSE orders_cursor;"
+""
+" OPEN order_line_cursor;"
+""
+" FOR i IN 0 .. 15 LOOP"
+" FETCH order_line_cursor INTO ol_i_id, ol_supply_w_id,"
+" ol_quantity, ol_amount,"
+" ol_delivery_d;"
+""
+" IF (order_line_cursor % NOTFOUND) THEN"
+" CLOSE order_line_cursor;"
+""
+" COMMIT WORK;"
+""
+" RETURN;"
+" END IF;"
+" END LOOP;"
+" ASSERT(0 = 1);"
+" "
+" END;"
+ ;
+
+ order_status_str = ut_str_catenate(str1, str2);
+ /*-----------------------------------------------------------*/
+
+ str1 =
+
+" PROCEDURE DELIVERY (w_id IN CHAR) IS"
+""
+" i INT;"
+" n_items INT;"
+" n_warehouses INT;"
+" n_districts INT;"
+" n_customers INT;"
+" d_id CHAR;"
+" c_id CHAR;"
+" o_id INT;"
+" o_carrier_id INT;"
+" ol_delivery_d INT;"
+" ol_total INT;"
+""
+" DECLARE CURSOR new_order_cursor IS"
+" SELECT NO_O_ID"
+" FROM NEW_ORDER"
+" WHERE NO_W_ID = w_id AND NO_D_ID = d_id"
+" ORDER BY NO_O_ID ASC;"
+""
+" DECLARE CURSOR orders_cursor IS"
+" SELECT O_C_ID"
+" FROM ORDERS"
+" WHERE O_W_ID = w_id AND O_D_ID = d_id"
+" AND O_ID = o_id"
+" FOR UPDATE;"
+" BEGIN"
+""
+" n_items := 200;"
+" n_warehouses := 1;"
+" n_districts := 10;"
+" n_customers := 20;"
+""
+" o_carrier_id := RND(1, 10);"
+" ol_delivery_d := SYSDATE();"
+
+ ;
+
+ str2 =
+
+" FOR i IN 1 .. n_districts LOOP"
+""
+" d_id := TO_BINARY(47 + i, 1);"
+""
+" OPEN new_order_cursor;"
+""
+" FETCH new_order_cursor INTO o_id;"
+""
+" IF (new_order_cursor % NOTFOUND) THEN"
+" /* PRINTF('No order to deliver'); */"
+""
+" CLOSE new_order_cursor;"
+" ELSE"
+" CLOSE new_order_cursor;"
+""
+" DELETE FROM NEW_ORDER"
+" WHERE NO_W_ID = w_id AND NO_D_ID = d_id"
+" AND NO_O_ID = o_id;"
+" OPEN orders_cursor;"
+""
+" FETCH orders_cursor INTO c_id;"
+""
+" UPDATE ORDERS SET O_CARRIER_ID = o_carrier_id"
+" WHERE CURRENT OF orders_cursor;"
+""
+" CLOSE orders_cursor;"
+""
+" UPDATE ORDER_LINE SET OL_DELIVERY_D = ol_delivery_d"
+" WHERE OL_W_ID = w_id AND OL_D_ID = d_id"
+" AND OL_O_ID = o_id;"
+""
+" SELECT SUM(OL_AMOUNT) INTO ol_total"
+" FROM ORDER_LINE"
+" WHERE OL_W_ID = w_id AND OL_D_ID = d_id"
+" AND OL_O_ID = o_id;"
+""
+" UPDATE CUSTOMER SET C_BALANCE = C_BALANCE - ol_total"
+" WHERE C_W_ID = w_id AND C_D_ID = d_id"
+" AND C_ID = c_id;"
+" END IF;"
+" END LOOP;"
+" COMMIT WORK;"
+""
+" "
+" END;"
+ ;
+
+ delivery_str = ut_str_catenate(str1, str2);
+
+ /*-----------------------------------------------------------*/
+
+ str =
+
+" PROCEDURE STOCK_LEVEL (w_id IN CHAR) IS"
+""
+" n_items INT;"
+" n_warehouses INT;"
+" n_districts INT;"
+" n_customers INT;"
+" d_id CHAR;"
+" o_id INT;"
+" stock_count INT;"
+" threshold INT;"
+""
+" BEGIN"
+""
+" n_items := 200;"
+" n_warehouses := 1;"
+" n_districts := 10;"
+" n_customers := 20;"
+""
+" d_id := TO_BINARY(47 + 4, 1);"
+""
+" threshold := RND(10, 20);"
+""
+" SELECT D_NEXT_O_ID INTO o_id"
+" FROM DISTRICT"
+" WHERE D_W_ID = w_id AND D_ID = d_id;"
+""
+" /* NOTE: COUNT(DISTINCT ...) not implemented yet: if we used a hash"
+" table, the DISTINCT operation should take at most 15 % more time */"
+""
+" SELECT COUNT(*) INTO stock_count"
+" FROM ORDER_LINE, STOCK"
+" WHERE OL_W_ID = w_id AND OL_D_ID = d_id"
+" AND OL_O_ID >= o_id - 10 AND OL_O_ID < o_id"
+" AND S_W_ID = w_id AND S_I_ID = OL_I_ID"
+" AND S_QUANTITY < threshold"
+" CONSISTENT READ;"
+" /* PRINTF(stock_count, ' items under threshold ', threshold); */"
+" COMMIT WORK;"
+""
+" END;"
+ ;
+
+ stock_level_str = str;
+
+ /*-----------------------------------------------------------*/
+
+ str =
+
+" PROCEDURE TPC_CONSISTENCY () IS"
+""
+" n_items INT;"
+" n_warehouses INT;"
+" n_districts INT;"
+" n_customers INT;"
+" n_orders INT;"
+" n_new_orders INT;"
+" n_order_lines INT;"
+" n_history INT;"
+" sum_order_quant INT;"
+" sum_stock_quant INT;"
+" n_delivered INT;"
+" n INT;"
+" n_new_order_lines INT;"
+" n_customers_d INT;"
+" n_regions INT;"
+" n_nations INT;"
+" n_suppliers INT;"
+" n_orders_d INT;"
+" n_lineitems INT;"
+""
+" BEGIN"
+""
+" PRINTF('TPC-C consistency check begins');"
+""
+" SELECT COUNT(*) INTO n_warehouses"
+" FROM WAREHOUSE;"
+" SELECT COUNT(*) INTO n_items"
+" FROM ITEM;"
+" SELECT COUNT(*) INTO n_customers"
+" FROM CUSTOMER;"
+" SELECT COUNT(*) INTO n_districts"
+" FROM DISTRICT;"
+" SELECT COUNT(*) INTO n_orders"
+" FROM ORDERS;"
+" SELECT COUNT(*) INTO n_new_orders"
+" FROM NEW_ORDER;"
+" SELECT COUNT(*) INTO n_order_lines"
+" FROM ORDER_LINE;"
+" SELECT COUNT(*) INTO n_history"
+" FROM HISTORY;"
+""
+" PRINTF('N warehouses ', n_warehouses);"
+""
+" PRINTF('N items ', n_items, ' : ', n_items / n_warehouses,"
+" ' per warehouse');"
+" PRINTF('N districts ', n_districts, ' : ', n_districts / n_warehouses,"
+" ' per warehouse');"
+" PRINTF('N customers ', n_customers, ' : ', n_customers / n_districts,"
+" ' per district');"
+" PRINTF('N orders ', n_orders, ' : ', n_orders / n_customers,"
+" ' per customer');"
+" PRINTF('N new orders ', n_new_orders, ' : ',"
+" n_new_orders / n_customers, ' per customer');"
+" PRINTF('N order lines ', n_order_lines, ' : ',"
+" n_order_lines / n_orders, ' per order');"
+" PRINTF('N history ', n_history, ' : ',"
+" n_history / n_customers, ' per customer');"
+" SELECT COUNT(*) INTO n_delivered"
+" FROM ORDER_LINE"
+" WHERE OL_DELIVERY_D < NULL;"
+""
+" PRINTF('N delivered order lines ', n_delivered);"
+""
+" SELECT COUNT(*) INTO n_new_order_lines"
+" FROM NEW_ORDER, ORDER_LINE"
+" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID"
+" AND NO_W_ID = OL_W_ID;"
+" PRINTF('N new order lines ', n_new_order_lines);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM NEW_ORDER, ORDER_LINE"
+" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID"
+" AND NO_W_ID = OL_W_ID AND OL_DELIVERY_D < NULL;"
+" PRINTF('Assertion 1');"
+" ASSERT(n = 0);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM NEW_ORDER, ORDER_LINE"
+" WHERE NO_O_ID = OL_O_ID AND NO_D_ID = OL_D_ID"
+" AND NO_W_ID = OL_W_ID AND OL_DELIVERY_D = NULL;"
+""
+" PRINTF('Assertion 2');"
+" ASSERT(n = n_new_order_lines);"
+" PRINTF('Assertion 2B');"
+" ASSERT(n_delivered + n_new_order_lines = n_order_lines);"
+""
+" PRINTF('Assertion 3');"
+" /* ASSERT(n_orders <= n_history); */"
+" PRINTF('Assertion 4');"
+" ASSERT(n_order_lines <= 15 * n_orders);"
+" PRINTF('Assertion 5');"
+" ASSERT(n_order_lines >= 5 * n_orders);"
+" PRINTF('Assertion 6');"
+" ASSERT(n_new_orders <= n_orders);"
+""
+" SELECT SUM(OL_QUANTITY) INTO sum_order_quant"
+" FROM ORDER_LINE;"
+" SELECT SUM(S_QUANTITY) INTO sum_stock_quant"
+" FROM STOCK;"
+" PRINTF('Sum order quant ', sum_order_quant, ' sum stock quant ',"
+" sum_stock_quant);"
+""
+" PRINTF('Assertion 7');"
+" ASSERT(((sum_stock_quant + sum_order_quant) / 91) * 91"
+" = sum_stock_quant + sum_order_quant);"
+" COMMIT WORK;"
+" PRINTF('TPC-C consistency check passed');"
+""
+" PRINTF('TPC-D consistency check begins');"
+""
+" SELECT COUNT(*) INTO n_customers_d"
+" FROM CUSTOMER_D"
+" CONSISTENT READ;"
+" SELECT COUNT(*) INTO n_nations"
+" FROM NATION"
+" CONSISTENT READ;"
+" SELECT COUNT(*) INTO n_regions"
+" FROM REGION"
+" CONSISTENT READ;"
+" SELECT COUNT(*) INTO n_suppliers"
+" FROM SUPPLIER"
+" CONSISTENT READ;"
+" SELECT COUNT(*) INTO n_orders_d"
+" FROM ORDERS_D"
+" CONSISTENT READ;"
+" SELECT COUNT(*) INTO n_lineitems"
+" FROM LINEITEM"
+" CONSISTENT READ;"
+""
+" PRINTF('N customers TPC-D ', n_customers_d);"
+""
+" PRINTF('N nations ', n_nations);"
+" PRINTF('N regions ', n_regions);"
+""
+" PRINTF('N suppliers ', n_suppliers);"
+" PRINTF('N orders TPC-D ', n_orders_d);"
+""
+" PRINTF('N lineitems ', n_lineitems, ' : ',"
+" n_lineitems / n_orders_d, ' per order');"
+" SELECT COUNT(*) INTO n"
+" FROM NATION, NATION_2"
+" WHERE N_NAME = N2_NAME"
+" CONSISTENT READ;"
+""
+" PRINTF('Assertion D1');"
+" ASSERT(n = n_nations);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM NATION, REGION"
+" WHERE N_REGIONKEY = R_REGIONKEY"
+" CONSISTENT READ;"
+""
+" PRINTF('Assertion D2');"
+" ASSERT(n = n_nations);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM ORDERS_D, CUSTOMER_D"
+" WHERE O_CUSTKEY = C_CUSTKEY"
+" CONSISTENT READ;"
+""
+" PRINTF('Assertion D3');"
+" ASSERT(n = n_orders_d);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM LINEITEM, SUPPLIER"
+" WHERE L_SUPPKEY = S_SUPPKEY"
+" CONSISTENT READ;"
+""
+" PRINTF('Assertion D4');"
+" ASSERT(n = n_lineitems);"
+""
+" SELECT COUNT(*) INTO n"
+" FROM ORDERS_D"
+" WHERE O_ORDERDATE >= 0"
+" AND O_ORDERDATE <= 2500"
+" CONSISTENT READ;"
+""
+" PRINTF('Assertion D5');"
+" ASSERT(n = n_orders_d);"
+""
+" COMMIT WORK;"
+" PRINTF('TPC-D consistency check passed');"
+""
+" END;"
+ ;
+
+ consistency_str = str;
+
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TPC_D_QUERY_5 (startday IN INT, endday IN INT) IS"
+""
+" revenue INT;"
+" r_name CHAR;"
+""
+" BEGIN"
+""
+" r_name := CONCAT('Region', TO_CHAR(3), ' ');"
+""
+" /* The last join to NATION_2 corresponds to calculating"
+" GROUP BY N_NAME in the original TPC-D query. It should take"
+" approximately the same amount of CPU time as GROUP BY. */"
+""
+" SELECT SUM((L_EXTENDEDPRICE * (100 - L_DISCOUNT)) / 100)"
+" INTO revenue"
+" FROM REGION, ORDERS_D, CUSTOMER_D, NATION,"
+" LINEITEM, SUPPLIER, NATION_2"
+" WHERE R_NAME = r_name"
+" AND O_ORDERDATE >= startday"
+" AND O_ORDERDATE < endday"
+" AND O_CUSTKEY = C_CUSTKEY"
+" AND C_NATIONKEY = N_NATIONKEY"
+" AND N_REGIONKEY = R_REGIONKEY"
+" AND O_ORDERKEY = L_ORDERKEY"
+" AND L_SUPPKEY = S_SUPPKEY"
+" AND S_NATIONKEY = C_NATIONKEY"
+" AND N_NAME = N2_NAME"
+" CONSISTENT READ;"
+""
+" PRINTF('Startdate ', startday, '; enddate ', endday,"
+" ': revenue ', revenue);"
+" COMMIT WORK;"
+""
+" END;"
+ ;
+
+ query_5_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE ROLLBACK_QUERY () IS"
+""
+" BEGIN"
+""
+" ROLLBACK WORK;"
+""
+" END;"
+ ;
+
+ rollback_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TEST_LOCK_WAIT () IS"
+""
+" w_id CHAR;"
+" BEGIN"
+""
+" w_id := TO_BINARY(1, 2);"
+" UPDATE WAREHOUSE SET W_YTD = W_YTD + 1 WHERE W_ID = w_id;"
+""
+" END;"
+ ;
+
+ lock_wait_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TEST_IBUF () IS"
+""
+" i INT;"
+" rnd INT;"
+" j INT;"
+" found INT;"
+""
+" DECLARE CURSOR desc_cursor IS"
+" SELECT IB_A"
+" FROM IBUF_TEST"
+" WHERE IB_A >= rnd AND IB_A < rnd + 50"
+" ORDER BY IB_A DESC;"
+""
+" BEGIN"
+""
+" PRINTF('Ibuf QUERY starts!!!!!!');"
+" rnd := RND(1, 1000);"
+""
+" FOR i IN 1 .. 50 LOOP"
+" INSERT INTO IBUF_TEST VALUES (rnd + i,"
+" RND_STR(RND(1, 2000)));"
+" END LOOP;"
+" IF (RND(1, 100) < 30) THEN"
+" PRINTF('Ibuf rolling back ---!!!');"
+" ROLLBACK WORK;"
+" END IF;"
+""
+""
+" IF (RND(1, 100) < 101) THEN"
+" rnd := RND(1, 1000);"
+" DELETE FROM IBUF_TEST WHERE IB_A >= rnd "
+" AND IB_A <= rnd + 50;"
+" END IF;"
+""
+" rnd := RND(1, 1000);"
+" SELECT COUNT(*) INTO j"
+" FROM IBUF_TEST"
+" WHERE IB_A >= rnd AND IB_A < rnd + 50;"
+""
+" PRINTF('Count: ', j);"
+""
+" rnd := RND(1, 1000);"
+" UPDATE IBUF_TEST"
+" SET IB_B = RND_STR(RND(1, 2000))"
+" WHERE IB_A >= rnd AND IB_A < rnd + 50;"
+""
+" OPEN desc_cursor;"
+""
+" rnd := RND(1, 1000);"
+" found := 1;"
+" WHILE (found > 0) LOOP"
+""
+" FETCH desc_cursor INTO j;"
+""
+" IF (desc_cursor % NOTFOUND) THEN"
+" found := 0;"
+" END IF;"
+" END LOOP;"
+""
+" CLOSE desc_cursor;"
+""
+" IF (RND(1, 100) < 30) THEN"
+" PRINTF('Ibuf rolling back!!!');"
+" ROLLBACK WORK;"
+" ELSE"
+" COMMIT WORK;"
+" END IF;"
+""
+" PRINTF('Ibuf QUERY ends!!!!!!');"
+" END;"
+ ;
+
+ ibuf_test_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TEST_GROUP_COMMIT (w_id IN CHAR) IS"
+""
+" i INT;"
+""
+" BEGIN"
+""
+" FOR i IN 1 .. 200 LOOP"
+" UPDATE WAREHOUSE SET W_YTD = W_YTD + 1 WHERE W_ID = w_id;"
+" COMMIT WORK;"
+" END LOOP;"
+" END;"
+ ;
+
+ test_group_commit_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TEST_SINGLE_ROW_SELECT ("
+" i_id IN CHAR,"
+" i_name OUT CHAR) IS"
+" BEGIN"
+" SELECT I_NAME INTO i_name"
+" FROM ITEM"
+" WHERE I_ID = i_id"
+" CONSISTENT READ;"
+" END;"
+ ;
+
+ test_single_row_select_str = str;
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE JOIN_TEST () IS"
+""
+" n_rows INT;"
+" i INT;"
+""
+" BEGIN"
+""
+" FOR i IN 0 .. 0 LOOP"
+" SELECT COUNT(*) INTO n_rows"
+" FROM JTEST1, JTEST2"
+" WHERE JT2_A = JT1_B"
+" CONSISTENT READ;"
+" PRINTF(n_rows);"
+""
+" COMMIT WORK;"
+" END LOOP;"
+""
+" END;"
+ ;
+
+ join_test_str = str;
+
+ /*-----------------------------------------------------------*/
+ str =
+
+" PROCEDURE TEST_ERRORS (switch IN CHAR) IS"
+""
+" count INT;"
+" val INT;"
+""
+" BEGIN"
+""
+" IF (switch = '01') THEN"
+" /* Test duplicate key error: run this first */"
+" ROW_PRINTF SELECT * FROM JTEST1;"
+" PRINTF('To insert first');"
+" INSERT INTO JTEST1 VALUES (1, 1);"
+" PRINTF('To insert second');"
+" INSERT INTO JTEST1 VALUES (2, 2);"
+" END IF;"
+""
+" IF (switch = '02') THEN"
+" /* Test duplicate key error: run this second */"
+" ROW_PRINTF SELECT * FROM JTEST1;"
+" PRINTF('To insert third');"
+" INSERT INTO JTEST1 VALUES (3, 3);"
+" ROW_PRINTF SELECT * FROM JTEST1;"
+" PRINTF('To insert fourth');"
+" INSERT INTO JTEST1 VALUES (1, 1);"
+" END IF;"
+""
+" IF (switch = '03') THEN"
+" /* Test duplicate key error: run this third */"
+" ROW_PRINTF SELECT * FROM JTEST1;"
+" PRINTF('Testing assert');"
+" SELECT COUNT(*) INTO count FROM JTEST1;"
+" ASSERT(count = 2);"
+" END IF;"
+""
+" IF (switch = '04') THEN"
+" /* Test duplicate key error: run this fourth */"
+" ROW_PRINTF SELECT * FROM JTEST1;"
+" PRINTF('Testing update');"
+" UPDATE JTEST1 SET JT1_A = 3 WHERE JT1_A = 2;"
+" PRINTF('Testing update');"
+" UPDATE JTEST1 SET JT1_A = 1 WHERE JT1_A = 3;"
+" END IF;"
+""
+" IF (switch = '05') THEN"
+" /* Test deadlock error: run this fifth in thread 1 */"
+" COMMIT WORK;"
+" PRINTF('Testing update in thread 1');"
+" UPDATE JTEST1 SET JT1_B = 3 WHERE JT1_A = 1;"
+" END IF;"
+""
+" IF (switch = '06') THEN"
+" /* Test deadlock error: run this sixth in thread 2 */"
+" PRINTF('Testing update in thread 2');"
+" UPDATE JTEST1 SET JT1_B = 10 WHERE JT1_A = 2;"
+" PRINTF('Testing update in thread 2');"
+" UPDATE JTEST1 SET JT1_B = 11 WHERE JT1_A = 1;"
+" PRINTF('Update in thread 2 completed');"
+" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 1;"
+" ASSERT(val = 11);"
+" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 2;"
+" ASSERT(val = 10);"
+" COMMIT WORK;"
+" END IF;"
+""
+" IF (switch = '07') THEN"
+" /* Test deadlock error: run this seventh in thread 1 */"
+" PRINTF('Testing update in thread 1: deadlock');"
+" UPDATE JTEST1 SET JT1_B = 4 WHERE JT1_A = 2;"
+" END IF;"
+""
+" IF (switch = '08') THEN"
+" /* Test deadlock error: run this eighth in thread 1 */"
+" PRINTF('Testing update in thread 1: commit');"
+" SELECT JT1_B INTO val FROM JTEST1 WHERE JT1_A = 1;"
+" ASSERT(val = 3);"
+" COMMIT WORK;"
+" END IF;"
+""
+" END;"
+ ;
+
+ test_errors_str = str;
+ /*-----------------------------------------------------------*/
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &create_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &populate_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)"use21", 5, (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ ret = SQLPrepare(stat, (UCHAR*)create_str, ut_strlen(create_str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ str = "{CREATE_TABLES()}";
+
+ ret = SQLPrepare(create_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(create_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ ret = SQLPrepare(stat, (UCHAR*)populate_str, ut_strlen(populate_str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)lock_wait_str,
+ ut_strlen(lock_wait_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)commit_str,
+ ut_strlen(commit_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)print_str,
+ ut_strlen(print_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)new_order_str,
+ ut_strlen(new_order_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)payment_str,
+ ut_strlen(payment_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)order_status_str,
+ ut_strlen(order_status_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)delivery_str,
+ ut_strlen(delivery_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)stock_level_str,
+ ut_strlen(stock_level_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)query_5_str,
+ ut_strlen(query_5_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)consistency_str,
+ ut_strlen(consistency_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)rollback_str, ut_strlen(rollback_str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)join_test_str,
+ ut_strlen(join_test_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)test_errors_str,
+ ut_strlen(test_errors_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)test_single_row_select_str,
+ ut_strlen(test_single_row_select_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)test_group_commit_str,
+ ut_strlen(test_group_commit_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLPrepare(stat, (UCHAR*)ibuf_test_str,
+ ut_strlen(ibuf_test_str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(stat);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ str = "{POPULATE_TABLES(?, ?)}";
+
+ ret = SQLPrepare(populate_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(populate_query, 1, SQL_PARAM_INPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&n_warehouses_buf,
+ 4, &n_warehouses_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ n_warehouses_buf = n_warehouses;
+ n_warehouses_len = 4;
+
+ ret = SQLBindParameter(populate_query, 2, SQL_PARAM_INPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&n_customers_d_buf,
+ 4, &n_customers_d_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ n_customers_d_buf = n_customers_d;
+ n_customers_d_len = 4;
+
+ ret = SQLExecute(populate_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ printf("TPC-C test database initialized\n");
+
+ return(0);
+}
+
+/*********************************************************************
+Iterates an SQL query until it returns SQL_SUCCESS. If it returns other
+value, rolls back the trx, prints an error message, and tries again. */
+
+void
+execute_until_success(
+/*==================*/
+ HSTMT query, /* in: query */
+ HSTMT rollback_query) /* in: trx rollback query to run if error */
+{
+ RETCODE ret;
+ UCHAR sql_state[6];
+ SDWORD native_error;
+ UCHAR error_msg[512];
+ SWORD error_msg_max = 512;
+ SWORD error_msg_len;
+
+ for (;;) {
+ ret = SQLExecute(query);
+
+ if (ret != SQL_SUCCESS) {
+ ut_a(ret == SQL_ERROR);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, query,
+ sql_state, &native_error, error_msg,
+ error_msg_max, &error_msg_len);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("%s\n", error_msg);
+
+ /* Roll back to release trx locks, and try again */
+
+ ret = SQLExecute(rollback_query);
+ ut_a(ret == SQL_SUCCESS);
+
+ os_thread_sleep(ut_rnd_gen_ulint() / 1000);
+ } else {
+
+ return;
+ }
+ }
+}
+
+/*********************************************************************
+Test for TPC-C. */
+
+ulint
+test_client(
+/*=========*/
+ void* arg) /* in: user name as a null-terminated string */
+{
+ ulint n_customers = 20;
+ ulint n_items = 200;
+ ulint n_lines;
+ bool put_invalid_item;
+ HENV env;
+ HDBC conn;
+ RETCODE ret;
+ HSTMT commit_query;
+ HSTMT new_order_query;
+ HSTMT payment_query;
+ HSTMT order_status_query;
+ HSTMT delivery_query;
+ HSTMT stock_level_query;
+ HSTMT print_query;
+ HSTMT lock_wait_query;
+ HSTMT join_test_query;
+ HSTMT test_group_commit_query;
+ HSTMT rollback_query;
+ HSTMT ibuf_query;
+ ulint tm, oldtm;
+ char* str;
+ byte c_w_id_buf[2];
+ byte c_d_id_buf[1];
+ byte c_id_buf[3];
+ byte ol_supply_w_ids_buf[30];
+ byte ol_i_ids_buf[45];
+ byte ol_quantities_buf[15];
+ byte c_last_buf[51];
+ byte c_credit_buf[3];
+ ulint c_discount_buf;
+ ulint w_tax_buf;
+ ulint d_tax_buf;
+ ulint o_ol_count_buf;
+ ulint o_id_buf;
+ ulint o_entry_d_buf;
+ ulint total_buf;
+ byte i_names_buf[361];
+ byte s_quantities_buf[60];
+ byte bg_buf[16];
+ byte i_prices_buf[60];
+ byte ol_amounts_buf[60];
+ SDWORD c_w_id_len;
+ SDWORD c_d_id_len;
+ SDWORD c_id_len;
+ SDWORD ol_supply_w_ids_len;
+ SDWORD ol_i_ids_len;
+ SDWORD ol_quantities_len;
+ SDWORD c_last_len;
+ SDWORD c_credit_len;
+ SDWORD c_discount_len;
+ SDWORD w_tax_len;
+ SDWORD d_tax_len;
+ SDWORD o_ol_count_len;
+ SDWORD o_id_len;
+ SDWORD o_entry_d_len;
+ SDWORD total_len;
+ SDWORD i_names_len;
+ SDWORD s_quantities_len;
+ SDWORD bg_len;
+ SDWORD i_prices_len;
+ SDWORD ol_amounts_len;
+ ulint i;
+ ulint k;
+ ulint t;
+
+ printf("Client thread %s\n", (UCHAR*)arg);
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &new_order_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &payment_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &order_status_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &delivery_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &stock_level_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &print_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &commit_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &lock_wait_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &join_test_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &test_group_commit_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &rollback_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &ibuf_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)arg, (SWORD)ut_strlen((char*)arg),
+ (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str =
+ "{NEW_ORDER(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,"
+ " ?, ?, ?, ?)}";
+
+ ret = SQLPrepare(new_order_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf,
+ 2, &c_w_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 2, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_d_id_buf,
+ 1, &c_d_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ c_d_id_len = 1;
+
+ ret = SQLBindParameter(new_order_query, 3, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_id_buf,
+ 3, &c_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ c_id_len = 3;
+
+ ret = SQLBindParameter(new_order_query, 4, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, ol_supply_w_ids_buf,
+ 30, &ol_supply_w_ids_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 5, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, ol_i_ids_buf,
+ 45, &ol_i_ids_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 6, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, ol_quantities_buf,
+ 15, &ol_quantities_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 7, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_last_buf,
+ 50, &c_last_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 8, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0,
+ (byte*)&c_credit_buf,
+ 2, &c_credit_len);
+ ut_a(ret == SQL_SUCCESS);
+ c_credit_buf[2] = '\0';
+
+ ret = SQLBindParameter(new_order_query, 9, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&c_discount_buf,
+ 4, &c_discount_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 10, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&w_tax_buf,
+ 4, &w_tax_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 11, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&d_tax_buf,
+ 4, &d_tax_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 12, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&o_ol_count_buf,
+ 4, &o_ol_count_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 13, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&o_id_buf,
+ 4, &o_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 14, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&o_entry_d_buf,
+ 4, &o_entry_d_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 15, SQL_PARAM_OUTPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)&total_buf,
+ 4, &total_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 16, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, i_names_buf,
+ 360, &i_names_len);
+ ut_a(ret == SQL_SUCCESS);
+ i_names_buf[360] = '\0';
+
+ ret = SQLBindParameter(new_order_query, 17, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, s_quantities_buf,
+ 60, &s_quantities_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 18, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, bg_buf,
+ 15, &bg_len);
+ ut_a(ret == SQL_SUCCESS);
+ bg_buf[15] = '\0';
+
+ ret = SQLBindParameter(new_order_query, 19, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, i_prices_buf,
+ 60, &i_prices_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(new_order_query, 20, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, ol_amounts_buf,
+ 60, &ol_amounts_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ c_w_id_len = 2;
+ c_w_id_buf[1] = (byte)(2 * atoi((char*)arg + 4));
+ c_w_id_buf[0] = (byte)(2 * (atoi((char*)arg + 4) / 256));
+
+ k = atoi((char*)arg + 4);
+
+ printf("Client thread %lu starts\n", k);
+
+ /*-----------------------------------------------------------*/
+ str = "{PAYMENT(?)}";
+
+ ret = SQLPrepare(payment_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(payment_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf,
+ 2, &c_w_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ str = "{ORDER_STATUS(?)}";
+
+ ret = SQLPrepare(order_status_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(order_status_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf,
+ 2, &c_w_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ str = "{DELIVERY(?)}";
+
+ ret = SQLPrepare(delivery_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(delivery_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf,
+ 2, &c_w_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ str = "{STOCK_LEVEL(?)}";
+
+ ret = SQLPrepare(stock_level_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(stock_level_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, c_w_id_buf,
+ 2, &c_w_id_len);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+ str = "{ROLLBACK_QUERY()}";
+
+ ret = SQLPrepare(rollback_query, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+ /*-----------------------------------------------------------*/
+
+ oldtm = ut_clock();
+
+ for (i = k; i < k + n_rounds / n_users; i++) {
+
+ /* execute_until_success(ibuf_query, rollback_query); */
+
+ if (i % 100 == 0) {
+ printf("User %s round %lu\n", (char*)arg, i);
+ }
+
+ if (!own_warehouse) {
+ c_w_id_buf[1] = (byte)ut_rnd_interval(1, n_warehouses);
+ c_w_id_buf[0] = (byte)(ut_rnd_interval(1, n_warehouses)
+ / 256);
+ }
+
+ mach_write_to_1(c_d_id_buf, (ut_rnd_interval(1, 10) + 47));
+ mach_write_to_3(c_id_buf, ut_rnd_interval(1, n_customers));
+
+ n_lines = ut_rnd_interval(5, 15);
+
+ if ((15 * k + i) % 100 == 0) {
+ put_invalid_item = TRUE;
+
+ /* printf("Will put invalid item\n"); */
+ } else {
+ put_invalid_item = FALSE;
+ }
+
+ for (t = 0; t < n_lines; t++) {
+ mach_write_to_3(ol_i_ids_buf + 3 * t,
+ ut_rnd_interval(1, n_items));
+
+ if (put_invalid_item && (t + 1 == n_lines)) {
+ mach_write_to_3(ol_i_ids_buf + 3 * t,
+ n_items + 1);
+ }
+
+ mach_write_to_1(ol_quantities_buf + t,
+ ut_rnd_interval(10, 20));
+ ut_memcpy(ol_supply_w_ids_buf + 2 * t, c_w_id_buf, 2);
+ }
+
+ ol_i_ids_len = 3 * n_lines;
+ ol_quantities_len = n_lines;
+ ol_supply_w_ids_len = 2 * n_lines;
+
+ execute_until_success(new_order_query, rollback_query);
+
+ if (put_invalid_item) {
+
+ goto skip_prints;
+ }
+/*
+ c_last_buf[c_last_len] = '\0';
+
+ printf(
+ "C_LAST %s, c_credit %s, c_discount, %lu, w_tax %lu, d_tax %lu\n",
+ c_last_buf, c_credit_buf, w_tax_buf, d_tax_buf);
+
+ printf("o_ol_count %lu, o_id %lu, o_entry_d %lu, total %lu\n",
+ o_ol_count_buf, o_id_buf, o_entry_d_buf,
+ total_buf);
+
+ ut_a(c_credit_len == 2);
+ ut_a(c_discount_len == 4);
+ ut_a(i_names_len == 360);
+
+ printf("i_names %s, bg %s\n", i_names_buf, bg_buf);
+
+ for (t = 0; t < n_lines; t++) {
+ printf("s_quantity %lu, i_price %lu, ol_amount %lu\n",
+ mach_read_from_4(s_quantities_buf + 4 * t),
+ mach_read_from_4(i_prices_buf + 4 * t),
+ mach_read_from_4(ol_amounts_buf + 4 * t));
+ }
+*/
+ skip_prints:
+ ;
+
+ execute_until_success(payment_query, rollback_query);
+
+ if (i % 10 == 3) {
+ execute_until_success(order_status_query,
+ rollback_query);
+ }
+
+ if ((i % 10 == 6) || (i % 100 == 60)) {
+ execute_until_success(delivery_query, rollback_query);
+ }
+
+ if (i % 10 == 9) {
+ execute_until_success(stock_level_query,
+ rollback_query);
+ }
+ }
+
+ tm = ut_clock();
+
+ printf("Wall time for %lu loops %lu milliseconds\n",
+ (i - k), tm - oldtm);
+
+/* execute_until_success(print_query, rollback_query); */
+
+ n_exited++;
+
+ printf("Client thread %lu exits as the %luth\n", k, n_exited);
+
+ return(0);
+}
+
+/*********************************************************************
+Test for single row select. */
+
+ulint
+test_single_row_select(
+/*===================*/
+ void* arg) /* in: user name as a null-terminated string */
+{
+ ulint n_items = 200;
+ HENV env;
+ HDBC conn;
+ RETCODE ret;
+ HSTMT single_row_select_query;
+ ulint tm, oldtm;
+ char* str;
+ byte i_id_buf[3];
+ byte i_name_buf[25];
+ SDWORD i_id_len;
+ SDWORD i_name_len;
+ ulint i;
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn, &single_row_select_query);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)arg,
+ (SWORD)ut_strlen((char*)arg),
+ (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str =
+ "{TEST_SINGLE_ROW_SELECT(?, ?)}";
+
+ ret = SQLPrepare(single_row_select_query, (UCHAR*)str,
+ ut_strlen(str));
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(single_row_select_query, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, i_id_buf,
+ 3, &i_id_len);
+ ut_a(ret == SQL_SUCCESS);
+ i_id_len = 3;
+
+ ret = SQLBindParameter(single_row_select_query, 2, SQL_PARAM_OUTPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, i_name_buf,
+ 24, &i_name_len);
+ ut_a(ret == SQL_SUCCESS);
+ i_name_buf[24] = '\0';
+
+ oldtm = ut_clock();
+
+ for (i = 0; i < 10000; i++) {
+
+ mach_write_to_3(i_id_buf, ut_rnd_interval(1, n_items));
+
+ ret = SQLExecute(single_row_select_query);
+
+ ut_a(ret == SQL_SUCCESS);
+ }
+
+ tm = ut_clock();
+
+ printf("Wall time for %lu single row selects %lu milliseconds\n",
+ i, tm - oldtm);
+ return(0);
+}
+
+/*********************************************************************
+TPC-D query 5. */
+
+ulint
+test_tpc_d_client(
+/*==============*/
+ void* arg) /* in: pointer to an array of startdate and enddate */
+{
+ char buf[20];
+ HENV env;
+ HDBC conn1;
+ RETCODE ret;
+ HSTMT query5;
+ HSTMT join_test;
+ char* str;
+ SDWORD len1;
+ SDWORD len2;
+ ulint i;
+ ulint tm, oldtm;
+
+ UT_NOT_USED(arg);
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn1, &query5);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn1, &join_test);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ sprintf(buf, "Use2%5lu", *((ulint*)arg));
+
+ ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)buf,
+ (SWORD)9, (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str = "{TPC_D_QUERY_5(?, ?)}";
+
+ ret = SQLPrepare(query5, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(query5, 1, SQL_PARAM_INPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)arg,
+ 4, &len1);
+ ut_a(ret == SQL_SUCCESS);
+
+ len1 = 4;
+
+ ret = SQLBindParameter(query5, 2, SQL_PARAM_INPUT,
+ SQL_C_LONG, SQL_INTEGER, 0, 0,
+ (byte*)arg + sizeof(ulint),
+ 4, &len2);
+ ut_a(ret == SQL_SUCCESS);
+
+ len2 = 4;
+
+ str = "{JOIN_TEST()}";
+
+ ret = SQLPrepare(join_test, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ for (i = 0; i < n_rounds; i++) {
+
+ oldtm = ut_clock();
+
+ ret = SQLExecute(query5);
+
+ /* ret = SQLExecute(join_test); */
+
+ ut_a(ret == SQL_SUCCESS);
+
+ tm = ut_clock();
+
+ printf("Wall time %lu milliseconds\n", tm - oldtm);
+ }
+
+ printf("%s exits\n", buf);
+
+ return(0);
+}
+
+/*********************************************************************
+Checks consistency of the TPC databases. */
+
+ulint
+check_tpc_consistency(
+/*==================*/
+ void* arg) /* in: user name */
+{
+ HENV env;
+ HDBC conn1;
+ RETCODE ret;
+ HSTMT consistency_query1;
+ char* str;
+
+ UT_NOT_USED(arg);
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn1, &consistency_query1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)arg,
+ (SWORD)ut_strlen((char*)arg), (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str = "{TPC_CONSISTENCY()}";
+
+ ret = SQLPrepare(consistency_query1, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLExecute(consistency_query1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Consistency checked\n");
+
+ return(0);
+}
+
+/*********************************************************************
+Test for errors. */
+
+ulint
+test_client_errors2(
+/*================*/
+ void* arg) /* in: ignored */
+{
+ HENV env;
+ HDBC conn1;
+ RETCODE ret;
+ HSTMT error_test_query1;
+ char* str;
+ byte buf1[2];
+ SDWORD len1;
+ UCHAR sql_state[6];
+ SDWORD native_error;
+ UCHAR error_msg[512];
+ SWORD error_msg_max = 512;
+ SWORD error_msg_len;
+
+ UT_NOT_USED(arg);
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn1, &error_test_query1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn1, (UCHAR*)cli_srv_endpoint_name,
+ (SWORD)ut_strlen(cli_srv_endpoint_name),
+ (UCHAR*)"conn2",
+ (SWORD)5, (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str = "{TEST_ERRORS(?)}";
+
+ ret = SQLPrepare(error_test_query1, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(error_test_query1, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, buf1,
+ 2, &len1);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+
+ printf("Thread 2 to do update\n");
+
+ ut_memcpy(buf1, "06", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Thread 2 has done update\n");
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_NO_DATA_FOUND);
+
+ return(0);
+}
+
+/*********************************************************************
+Test for errors. */
+
+ulint
+test_client_errors(
+/*===============*/
+ void* arg) /* in: ignored */
+{
+ HENV env;
+ HDBC conn1;
+ RETCODE ret;
+ HSTMT error_test_query1;
+ char* str;
+ byte buf1[2];
+ SDWORD len1;
+ UCHAR sql_state[6];
+ SDWORD native_error;
+ UCHAR error_msg[512];
+ SWORD error_msg_max = 512;
+ SWORD error_msg_len;
+ os_thread_id_t thread_id;
+
+ UT_NOT_USED(arg);
+
+ ret = SQLAllocEnv(&env);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocConnect(env, &conn1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLAllocStmt(conn1, &error_test_query1);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLConnect(conn1, (UCHAR*)"innobase", 8, (UCHAR*)"conn1",
+ (SWORD)5, (UCHAR*)"password", 8);
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("Connection established\n");
+
+ /*-----------------------------------------------------------*/
+ str = "{TEST_ERRORS(?)}";
+
+ ret = SQLPrepare(error_test_query1, (UCHAR*)str, ut_strlen(str));
+
+ ut_a(ret == SQL_SUCCESS);
+
+ ret = SQLBindParameter(error_test_query1, 1, SQL_PARAM_INPUT,
+ SQL_C_CHAR, SQL_CHAR, 0, 0, buf1,
+ 2, &len1);
+ ut_a(ret == SQL_SUCCESS);
+
+ /*-----------------------------------------------------------*/
+
+ ut_memcpy(buf1, "01", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ ut_memcpy(buf1, "02", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_ERROR);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("%s\n", error_msg);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_NO_DATA_FOUND);
+
+ ut_memcpy(buf1, "03", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ ut_memcpy(buf1, "01", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_ERROR);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("%s\n", error_msg);
+
+ ut_memcpy(buf1, "03", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ ut_memcpy(buf1, "04", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_ERROR);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("%s\n", error_msg);
+
+ ut_memcpy(buf1, "03", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ ut_memcpy(buf1, "05", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ os_thread_create(&test_client_errors2, "user000", &thread_id);
+
+ os_thread_sleep(5000000);
+
+ ut_memcpy(buf1, "07", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_ERROR);
+
+ ret = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, error_test_query1,
+ sql_state, &native_error, error_msg, error_msg_max,
+ &error_msg_len);
+
+ ut_a(ret == SQL_SUCCESS);
+
+ printf("%s\n", error_msg);
+
+ printf("Thread 1 to commit\n");
+
+ ut_memcpy(buf1, "08", 2);
+ len1 = 2;
+ ret = SQLExecute(error_test_query1);
+ ut_a(ret == SQL_SUCCESS);
+
+ return(0);
+}
+
+/*************************************************************************
+Simulates disk waits: if there are at least two threads active,
+puts the current thread to wait for an event. If there is just the current
+thread active and another thread doing a simulated disk wait, puts the
+current thread to wait and releases another thread from wait, otherwise does
+nothing */
+
+void
+srv_simulate_disk_wait(void)
+/*========================*/
+{
+ os_event_t event;
+ ulint wait_i;
+ ulint count;
+ bool found;
+ ulint rnd;
+ ulint i;
+ ulint j;
+
+ mutex_enter(&kernel_mutex);
+
+ srv_disk_rnd += 98687241;
+
+ count = 0;
+ found = FALSE;
+
+ for (i = 0; i < SRV_N_SIM_DISK_ARRAY; i++) {
+
+ if (!srv_sim_disk[i].empty) {
+
+ count++;
+ }
+
+ if (!found && srv_sim_disk[i].empty) {
+
+ srv_sim_disk[i].empty = FALSE;
+ event = srv_sim_disk[i].event;
+
+ os_event_reset(event);
+ srv_sim_disk[i].event_set = FALSE;
+
+ wait_i = i;
+
+ found = TRUE;
+ }
+ }
+
+ ut_a(found);
+
+ if (srv_disk_n_active_threads == count + 1) {
+ /* We have to release a thread from the disk wait array */;
+
+ rnd = srv_disk_rnd;
+
+ for (i = rnd; i < SRV_N_SIM_DISK_ARRAY + rnd; i++) {
+
+ j = i % SRV_N_SIM_DISK_ARRAY;
+
+ if (!srv_sim_disk[j].empty
+ && !srv_sim_disk[j].event_set) {
+
+ srv_sim_disk[j].event_set = TRUE;
+ os_event_set(srv_sim_disk[j].event);
+
+ break;
+ }
+ }
+ }
+
+ mutex_exit(&kernel_mutex);
+
+ os_event_wait(event);
+
+ mutex_enter(&kernel_mutex);
+
+ srv_sim_disk[wait_i].empty = TRUE;
+
+ mutex_exit(&kernel_mutex);
+}
+
+/*************************************************************************
+Releases a thread from the simulated disk wait array if there is any to
+release. */
+
+void
+srv_simulate_disk_wait_release(void)
+/*================================*/
+{
+ ulint rnd;
+ ulint i;
+ ulint j;
+
+ mutex_enter(&kernel_mutex);
+
+ srv_disk_rnd += 98687241;
+ rnd = srv_disk_rnd;
+
+ for (i = rnd; i < SRV_N_SIM_DISK_ARRAY + rnd; i++) {
+
+ j = i % SRV_N_SIM_DISK_ARRAY;
+
+ if (!srv_sim_disk[j].empty
+ && !srv_sim_disk[j].event_set) {
+
+ srv_sim_disk[j].event_set = TRUE;
+ os_event_set(srv_sim_disk[j].event);
+
+ break;
+ }
+ }
+
+ mutex_exit(&kernel_mutex);
+}
+
+/*********************************************************************
+Test for many threads and disk waits. */
+
+ulint
+test_disk_waits(
+/*============*/
+ void* arg) /* in: ignored */
+{
+ ulint i;
+ ulint tm, oldtm;
+
+ UT_NOT_USED(arg);
+
+ n_exited++;
+
+ printf("Client thread starts as the %luth\n", n_exited);
+
+ oldtm = ut_clock();
+
+ mutex_enter(&kernel_mutex);
+ srv_disk_n_active_threads++;
+ mutex_exit(&kernel_mutex);
+
+ for (i = 0; i < 133; i++) {
+ ut_delay(500);
+
+/* os_thread_yield(); */
+
+/* os_thread_sleep(10000); */
+
+ srv_simulate_disk_wait();
+ }
+
+ mutex_enter(&kernel_mutex);
+ srv_disk_n_active_threads--;
+ mutex_exit(&kernel_mutex);
+
+ srv_simulate_disk_wait_release();
+
+ tm = ut_clock();
+
+ printf("Wall time for %lu loops %lu milliseconds\n", i, tm - oldtm);
+
+ n_exited++;
+
+ printf("Client thread exits as the %luth\n", n_exited);
+
+ return(0);
+}
+
+/*************************************************************************
+Reads a keywords and a values from an initfile. In case of an error, exits
+from the process. */
+
+void
+cli_read_initfile(
+/*==============*/
+ FILE* initfile) /* in: file pointer */
+{
+ char str_buf[10000];
+ ulint ulint_val;
+
+ srv_read_init_val(initfile, FALSE, "SRV_ENDPOINT_NAME", str_buf,
+ &ulint_val);
+ ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN);
+
+ ut_memcpy(cli_srv_endpoint_name, str_buf, COM_MAX_ADDR_LEN);
+
+ srv_read_init_val(initfile, FALSE, "USER_NAME", str_buf,
+ &ulint_val);
+ ut_a(ut_strlen(str_buf) < COM_MAX_ADDR_LEN);
+
+ ut_memcpy(cli_user_name, str_buf, COM_MAX_ADDR_LEN);
+
+ srv_read_init_val(initfile, TRUE, "MEM_POOL_SIZE", str_buf,
+ &mem_pool_size);
+
+ srv_read_init_val(initfile, TRUE, "N_WAREHOUSES", str_buf,
+ &n_warehouses);
+
+ srv_read_init_val(initfile, TRUE, "N_CUSTOMERS_D", str_buf,
+ &n_customers_d);
+
+ srv_read_init_val(initfile, TRUE, "IS_TPC_D", str_buf,
+ &is_tpc_d);
+
+ srv_read_init_val(initfile, TRUE, "N_ROUNDS", str_buf,
+ &n_rounds);
+
+ srv_read_init_val(initfile, TRUE, "N_USERS", str_buf,
+ &n_users);
+
+ srv_read_init_val(initfile, TRUE, "STARTDATE", str_buf,
+ &startdate);
+
+ srv_read_init_val(initfile, TRUE, "ENDDATE", str_buf,
+ &enddate);
+
+ srv_read_init_val(initfile, TRUE, "OWN_WAREHOUSE", str_buf,
+ &own_warehouse);
+}
+
+/*************************************************************************
+*/
+void
+cli_boot(
+/*=====*/
+ char* name) /* in: the initialization file name */
+{
+ FILE* initfile;
+
+ initfile = fopen(name, "r");
+
+ if (initfile == NULL) {
+ printf(
+ "Error in client booting: could not open initfile whose name is %s!\n",
+ name);
+ os_process_exit(1);
+ }
+
+ cli_read_initfile(initfile);
+
+ fclose(initfile);
+}
+
+/********************************************************************
+Main test function. */
+
+void
+main(void)
+/*======*/
+{
+ os_thread_t thread_handles[1000];
+ os_thread_id_t thread_ids[1000];
+ char user_names[1000];
+ ulint tm, oldtm;
+ ulint i;
+ ulint dates[1000];
+
+ cli_boot("cli_init");
+
+ for (i = 1; i <= n_users; i++) {
+ dates[2 * i] = startdate
+ + ((enddate - startdate) / n_users) * (i - 1);
+ dates[2 * i + 1] = startdate
+ + ((enddate - startdate) / n_users) * i;
+ }
+
+ sync_init();
+
+ mem_init(mem_pool_size);
+
+ test_init(NULL);
+
+ check_tpc_consistency("con21");
+
+/* test_client_errors(NULL); */
+
+ os_thread_sleep(4000000);
+
+ printf("Sleep ends\n");
+
+ oldtm = ut_clock();
+
+ for (i = 2; i <= n_users; i++) {
+ if (is_tpc_d) {
+ thread_handles[i] = os_thread_create(&test_tpc_d_client,
+ dates + 2 * i, thread_ids + i);
+ } else {
+ sprintf(user_names + i * 8, "use2%3lu", i);
+
+ thread_handles[i] = os_thread_create(&test_client,
+ user_names + i * 8, thread_ids + i);
+ }
+
+ ut_a(thread_handles[i]);
+ }
+
+ if (is_tpc_d) {
+ test_tpc_d_client(dates + 2 * 1);
+ } else {
+ test_client("use2 1");
+ }
+
+ for (i = 2; i <= n_users; i++) {
+ os_thread_wait(thread_handles[i]);
+
+ printf("Wait for thread %lu ends\n", i);
+ }
+
+ tm = ut_clock();
+
+ printf("Wall time for test %lu milliseconds\n", tm - oldtm);
+
+ os_thread_sleep(4000000);
+
+ printf("Sleep ends\n");
+
+ test_single_row_select("con99");
+
+ check_tpc_consistency("con22");
+
+ printf("TESTS COMPLETED SUCCESSFULLY!\n");
+}