mirror of
https://github.com/MariaDB/server.git
synced 2025-01-27 01:04:19 +01:00
2662b59306
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
3380 lines
76 KiB
C
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");
|
|
}
|