Line data Source code
1 : /*
2 : * Test bulk copy in using array binding and blk_rowxfer_mult.
3 : * Check the row count passed to blk_rowxfer_mult, behaviour taken
4 : * from Sybase/SAP library.
5 : */
6 :
7 : #include "common.h"
8 :
9 : #include <bkpublic.h>
10 :
11 : static const char table_name[] = "blk_in_array_test";
12 :
13 : static CS_CONNECTION *conn;
14 : static CS_COMMAND *cmd;
15 :
16 : /* check rows in table and their sum, also checks connection is usable */
17 : static void
18 70 : check_table(CS_INT expected_count, CS_INT expected_sum)
19 : {
20 : char sql[128];
21 : CS_DATAFMT fmt;
22 : CS_INT values[2], result_type, count;
23 : CS_RETCODE ret;
24 : int i;
25 :
26 70 : sprintf(sql, "select count(*), coalesce(sum(id), 0) from %s", table_name);
27 70 : check_call(ct_command, (cmd, CS_LANG_CMD, sql, CS_NULLTERM, CS_UNUSED));
28 70 : check_call(ct_send, (cmd));
29 280 : while ((ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
30 140 : if (result_type != CS_ROW_RESULT)
31 70 : continue;
32 140 : for (i = 0; i < 2; i++) {
33 140 : memset(&fmt, 0, sizeof(fmt));
34 140 : fmt.datatype = CS_INT_TYPE;
35 140 : fmt.maxlength = sizeof(CS_INT);
36 140 : fmt.count = 1;
37 140 : check_call(ct_bind, (cmd, i + 1, &fmt, &values[i], NULL, NULL));
38 : }
39 140 : while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
40 70 : continue;
41 70 : assert(ret == CS_END_DATA);
42 : }
43 70 : assert(ret == CS_END_RESULTS);
44 :
45 70 : if (values[0] != expected_count || values[1] != expected_sum) {
46 0 : fprintf(stderr, "wrong table content, got %d rows sum %d, expected %d rows sum %d\n",
47 0 : (int) values[0], (int) values[1], (int) expected_count, (int) expected_sum);
48 0 : exit(1);
49 : }
50 70 : }
51 :
52 : /*
53 : * Bulk copy 3 bound rows (ids 1, 2 and 3) calling blk_rowxfer_mult
54 : * with given row count (NULL if row_count is NULL).
55 : */
56 : static void
57 70 : test(const CS_INT *row_count, CS_RETCODE expected_ret, CS_INT expected_rows)
58 : {
59 : CS_BLKDESC *blkdesc;
60 : CS_DATAFMT fmt;
61 70 : CS_INT ids[3] = { 1, 2, 3 }, lens[3] = { 4, 4, 4 };
62 70 : CS_INT count = 0, rows = -1;
63 : CS_RETCODE ret;
64 : char sql[128];
65 :
66 70 : printf("row count %s%d\n", row_count ? "" : "NULL ", row_count ? (int) *row_count : 0);
67 :
68 70 : sprintf(sql, "delete from %s", table_name);
69 70 : check_call(run_command, (cmd, sql));
70 :
71 70 : check_call(blk_alloc, (conn, BLK_VERSION_100, &blkdesc));
72 70 : check_call(blk_init, (blkdesc, CS_BLK_IN, (char *) table_name, CS_NULLTERM));
73 :
74 70 : memset(&fmt, 0, sizeof(fmt));
75 70 : fmt.datatype = CS_INT_TYPE;
76 70 : fmt.maxlength = sizeof(CS_INT);
77 70 : fmt.count = 3;
78 70 : check_call(blk_bind, (blkdesc, 1, &fmt, ids, lens, NULL));
79 :
80 70 : if (row_count)
81 60 : count = *row_count;
82 70 : ct_reset_last_message();
83 70 : ret = blk_rowxfer_mult(blkdesc, row_count ? &count : NULL);
84 70 : if (ret != expected_ret) {
85 0 : fprintf(stderr, "blk_rowxfer_mult returned %d, expected %d\n", (int) ret, (int) expected_ret);
86 0 : exit(1);
87 : }
88 70 : if (expected_ret == CS_FAIL)
89 10 : check_last_message(CTMSG_CLIENT, 0x01010121, "row count greater than the array bind count");
90 :
91 70 : check_call(blk_done, (blkdesc, CS_BLK_ALL, &rows));
92 70 : if (rows != expected_rows) {
93 0 : fprintf(stderr, "blk_done returned %d rows, expected %d\n", (int) rows, (int) expected_rows);
94 0 : exit(1);
95 : }
96 70 : blk_drop(blkdesc);
97 :
98 70 : check_table(expected_rows, expected_rows * (expected_rows + 1) / 2);
99 70 : }
100 :
101 10 : TEST_MAIN()
102 : {
103 : CS_CONTEXT *ctx;
104 10 : bool verbose = false;
105 : char sql[256];
106 : CS_INT row_count;
107 :
108 10 : printf("%s: Testing bulk copy in using array binding\n", __FILE__);
109 10 : check_call(try_ctlogin, (&ctx, &conn, &cmd, verbose));
110 :
111 10 : sprintf(sql, "if exists (select 1 from sysobjects where type = 'U' and name = '%s') drop table %s", table_name, table_name);
112 10 : check_call(run_command, (cmd, sql));
113 10 : sprintf(sql, "create table %s (id int not null)", table_name);
114 10 : check_call(run_command, (cmd, sql));
115 :
116 : /* NULL, zero or negative values send all bound rows */
117 10 : test(NULL, CS_SUCCEED, 3);
118 10 : row_count = 0;
119 10 : test(&row_count, CS_SUCCEED, 3);
120 10 : row_count = -1;
121 10 : test(&row_count, CS_SUCCEED, 3);
122 :
123 : /* positive values limit rows sent */
124 10 : row_count = 1;
125 10 : test(&row_count, CS_SUCCEED, 1);
126 10 : row_count = 2;
127 10 : test(&row_count, CS_SUCCEED, 2);
128 10 : row_count = 3;
129 10 : test(&row_count, CS_SUCCEED, 3);
130 :
131 : /* cannot send more rows than bound */
132 10 : row_count = 4;
133 10 : test(&row_count, CS_FAIL, 0);
134 :
135 10 : sprintf(sql, "drop table %s", table_name);
136 10 : check_call(run_command, (cmd, sql));
137 :
138 10 : printf("done\n");
139 :
140 10 : check_call(try_ctlogout, (ctx, conn, cmd, verbose));
141 :
142 10 : return 0;
143 : }
|