Line data Source code
1 : #include "common.h"
2 :
3 : /* Test for {?=call store(?)} syntax and run */
4 :
5 : static void test_with_conversions(void);
6 : static void test_with_dbname(void);
7 :
8 : int
9 8 : main(void)
10 : {
11 : SQLINTEGER input, output;
12 : SQLLEN ind, ind2, ind3, ind4;
13 : SQLINTEGER out1;
14 : char out2[30];
15 :
16 8 : odbc_connect();
17 :
18 8 : odbc_command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
19 :
20 8 : odbc_command("create proc simpleresult @i int as begin return @i end");
21 :
22 8 : CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
23 8 : CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
24 :
25 8 : CHKPrepare(T("{ \n?\t\r= call simpleresult(?)}"), SQL_NTS, "S");
26 :
27 8 : input = 123;
28 8 : ind2 = sizeof(input);
29 8 : output = 0xdeadbeef;
30 8 : CHKExecute("S");
31 :
32 8 : if (output != 123) {
33 0 : printf("Invalid result\n");
34 0 : exit(1);
35 : }
36 :
37 : /* should return "Invalid cursor state" */
38 8 : if (SQLFetch(odbc_stmt) != SQL_ERROR) {
39 0 : printf("Data not expected\n");
40 0 : exit(1);
41 : }
42 8 : ODBC_CHECK_COLS(0);
43 :
44 : /* just to reset some possible buffers */
45 8 : odbc_command("DECLARE @i INT");
46 :
47 : /* same test but with SQLExecDirect and same bindings */
48 8 : input = 567;
49 8 : ind2 = sizeof(input);
50 8 : output = 0xdeadbeef;
51 8 : CHKExecDirect(T("{?=call simpleresult(?)}"), SQL_NTS, "S");
52 :
53 8 : if (output != 567) {
54 0 : fprintf(stderr, "Invalid result\n");
55 0 : exit(1);
56 : }
57 :
58 : /* should return "Invalid cursor state" */
59 8 : CHKFetch("E");
60 :
61 8 : odbc_command("drop proc simpleresult");
62 :
63 8 : odbc_command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
64 :
65 : /* force cursor close */
66 8 : SQLCloseCursor(odbc_stmt);
67 :
68 : /* test output parameter */
69 8 : odbc_command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
70 :
71 8 : CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
72 8 : CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
73 8 : CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind3, "S");
74 8 : CHKBindParameter(4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, out2, sizeof(out2), &ind4, "S");
75 :
76 8 : CHKPrepare(T("{ \n?\t\r= call simpleresult2(?,?,?)}"), SQL_NTS, "S");
77 :
78 8 : input = 987;
79 8 : ind2 = sizeof(input);
80 8 : out1 = 888;
81 8 : output = 0xdeadbeef;
82 8 : ind3 = SQL_DATA_AT_EXEC;
83 8 : ind4 = SQL_DEFAULT_PARAM;
84 8 : strcpy(out2, "bad!");
85 8 : CHKExecute("S");
86 :
87 8 : if (output != 987 || ind3 <= 0 || ind4 <= 0 || out1 != 6789 || strcmp(out2, "test foo") != 0) {
88 0 : printf("ouput = %d ind3 = %d ind4 = %d out1 = %d out2 = %s\n", (int) output, (int) ind3, (int) ind4, (int) out1,
89 : out2);
90 0 : printf("Invalid result\n");
91 0 : exit(1);
92 : }
93 :
94 : /* should return "Invalid cursor state" */
95 8 : CHKFetch("E");
96 :
97 8 : ODBC_CHECK_COLS(0);
98 :
99 8 : odbc_command("drop proc simpleresult2");
100 :
101 : /*
102 : * test from shiv kumar
103 : * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
104 : * SQLBindParameter call is not working on AIX"
105 : */
106 8 : odbc_command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
107 :
108 8 : odbc_reset_statement();
109 :
110 8 : odbc_command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
111 8 : SQLCloseCursor(odbc_stmt);
112 :
113 8 : CHKPrepare(T("{ ? = CALL rpc_read ( ?, ? ) }"), SQL_NTS, "S");
114 :
115 8 : ind = 0;
116 8 : CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
117 :
118 8 : ind2 = 0;
119 8 : CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
120 :
121 8 : ind3 = 8;
122 8 : CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3, "S");
123 :
124 8 : CHKExecute("S");
125 :
126 8 : CHKFetch("S");
127 :
128 8 : CHKFetch("No");
129 :
130 8 : odbc_reset_statement();
131 8 : odbc_command("drop proc rpc_read");
132 :
133 : /*
134 : * Test from Joao Amaral
135 : * This test SQLExecute where a store procedure returns no result
136 : * This seems similar to a previous one but use set instead of select
137 : * (with is supported only by mssql and do not return all stuff as
138 : * select does)
139 : */
140 8 : if (odbc_db_is_microsoft()) {
141 :
142 6 : odbc_reset_statement();
143 :
144 6 : odbc_command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
145 6 : odbc_command("create proc sp_test @res int output as set @res = 456");
146 :
147 6 : odbc_reset_statement();
148 :
149 6 : CHKPrepare(T("{ call sp_test(?)}"), SQL_NTS, "S");
150 6 : CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
151 :
152 6 : output = 0xdeadbeef;
153 6 : CHKExecute("S");
154 :
155 6 : if (output != 456) {
156 0 : fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
157 0 : return 1;
158 : }
159 6 : odbc_command("drop proc sp_test");
160 : }
161 8 : odbc_disconnect();
162 :
163 8 : if (odbc_db_is_microsoft()) {
164 6 : odbc_use_version3 = 1;
165 6 : odbc_connect();
166 :
167 6 : test_with_conversions();
168 6 : test_with_dbname();
169 6 : odbc_disconnect();
170 : }
171 :
172 8 : printf("Done.\n");
173 8 : return 0;
174 : }
175 :
176 : static void
177 6 : test_with_conversions(void)
178 : {
179 : SQLLEN ind, ind2, ind3;
180 : char out2[30];
181 :
182 : /*
183 : * test from Bower, Wayne
184 : * Cfr ML 2012-03-02 "[freetds] [unixODBC][Driver Manager]Function sequence error (SQL-HY010)"
185 : */
186 6 : odbc_command("IF OBJECT_ID('TMP_SP_Test_ODBC') IS NOT NULL DROP PROC TMP_SP_Test_ODBC");
187 6 : odbc_command("create proc TMP_SP_Test_ODBC @i int,\n@o int output\nas\nset nocount on\nselect @o = 55\nreturn 9\n");
188 6 : odbc_reset_statement();
189 :
190 6 : CHKPrepare(T("{ ? = call TMP_SP_Test_ODBC (?, ?) }"), SQL_NTS, "S");
191 :
192 6 : ind2 = 2;
193 6 : CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 80, 0, "10", 2, &ind2, "S");
194 6 : ind3 = SQL_NULL_DATA;
195 6 : strcpy(out2, " ");
196 6 : CHKBindParameter(3, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 1, out2, 29, &ind3, "S");
197 6 : ind = 1;
198 6 : CHKBindParameter(1, SQL_PARAM_INPUT_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 0, 1, out2, 29, &ind, "S");
199 :
200 : /* mssql returns SUCCESS */
201 6 : CHKExecute("No");
202 :
203 6 : ODBC_CHECK_COLS(0);
204 :
205 6 : odbc_reset_statement();
206 6 : odbc_command("drop proc TMP_SP_Test_ODBC");
207 6 : }
208 :
209 : static void
210 6 : test_with_dbname(void)
211 : {
212 : SQLINTEGER len;
213 : SQLTCHAR out[512];
214 : char sql[1024];
215 : SQLINTEGER output;
216 : SQLLEN ind;
217 6 : ODBC_BUF *odbc_buf = NULL;
218 :
219 6 : len = sizeof(out);
220 6 : CHKGetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) out, sizeof(out), &len, "SI");
221 :
222 6 : odbc_command("IF OBJECT_ID('TMP_SP_Test_ODBC') IS NOT NULL DROP PROC TMP_SP_Test_ODBC");
223 6 : odbc_command("create proc TMP_SP_Test_ODBC @o int output\nas\nset @o=55\nreturn 3\n");
224 6 : odbc_reset_statement();
225 :
226 6 : sprintf(sql, "{call [%s]..TMP_SP_Test_ODBC(?)}", C(out));
227 6 : CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
228 6 : CHKPrepare(T(sql), SQL_NTS, "S");
229 :
230 6 : output = 123;
231 6 : ind = sizeof(output);
232 6 : CHKExecute("S");
233 :
234 6 : if (output != 55) {
235 0 : printf("Invalid result\n");
236 0 : exit(1);
237 : }
238 :
239 6 : odbc_reset_statement();
240 6 : odbc_command("drop proc TMP_SP_Test_ODBC");
241 6 : ODBC_FREE();
242 6 : }
|