mariadb/innobase/btr/ts/tscli.c
unknown 2662b59306 Added Innobase to source distribution
Docs/manual.texi:
  Added Innobase documentation
configure.in:
  Incremented version
include/my_base.h:
  Added option for Innobase
myisam/mi_check.c:
  cleanup
mysql-test/t/bdb.test:
  cleanup
mysql-test/t/innobase.test:
  Extended with new tests from bdb.test
mysql-test/t/merge.test:
  Added test of SHOW create
mysys/my_init.c:
  Fix for UNIXWARE 7
scripts/mysql_install_db.sh:
  Always write how to start mysqld
scripts/safe_mysqld.sh:
  Fixed type
sql/ha_innobase.cc:
  Update to new version
sql/ha_innobase.h:
  Update to new version
sql/handler.h:
  Added 'update_table_comment()' and 'append_create_info()'
sql/sql_delete.cc:
  Fixes for Innobase
sql/sql_select.cc:
  Fixes for Innobase
sql/sql_show.cc:
  Append create information (for MERGE tables)
sql/sql_update.cc:
  Fixes for Innobase
2001-02-17 14:19:19 +02:00

3380 lines
76 KiB
C

/************************************************************************
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");
}