Line data Source code
1 : /*
2 : * Test reading data with SQLGetData
3 : */
4 : #include "common.h"
5 : #include <assert.h>
6 :
7 : static void
8 50 : test_err(const char *data, int c_type, const char *state)
9 : {
10 : char sql[128];
11 : SQLLEN ind;
12 50 : const unsigned int buf_size = 128;
13 50 : char *buf = (char *) malloc(buf_size);
14 :
15 50 : sprintf(sql, "SELECT '%s'", data);
16 50 : odbc_command(sql);
17 50 : SQLFetch(odbc_stmt);
18 50 : CHKGetData(1, c_type, buf, buf_size, &ind, "E");
19 50 : free(buf);
20 50 : odbc_read_error();
21 50 : if (strcmp(odbc_sqlstate, state) != 0) {
22 0 : fprintf(stderr, "Unexpected sql state returned\n");
23 0 : odbc_disconnect();
24 0 : exit(1);
25 : }
26 50 : odbc_reset_statement();
27 50 : }
28 :
29 : static int lc;
30 : static int type;
31 :
32 : static int
33 144 : mycmp(const char *s1, const char *s2)
34 : {
35 : SQLWCHAR buf[128], *wp;
36 : size_t l;
37 :
38 144 : if (type == SQL_C_CHAR)
39 72 : return strcmp(s1, s2);
40 :
41 72 : l = strlen(s2);
42 72 : assert(l < TDS_VECTOR_SIZE(buf));
43 : wp = buf;
44 : do {
45 558 : *wp++ = *s2;
46 558 : } while (*s2++);
47 :
48 72 : return memcmp(s1, buf, l * lc + lc);
49 : }
50 :
51 : static void
52 36 : test_split(const char *n_flag)
53 : {
54 : #define CheckLen(x) do { \
55 : if (len != (x)) { \
56 : fprintf(stderr, "Wrong len %ld at line %d expected %d\n", (long int) len, __LINE__, (x)); \
57 : exit(1); \
58 : } \
59 : } while(0)
60 :
61 : char *sql;
62 36 : char *buf = NULL;
63 36 : const char *collate = "";
64 : SQLLEN len;
65 :
66 : /* TODO test with VARCHAR too */
67 36 : if (odbc_db_is_microsoft())
68 32 : collate = " COLLATE Latin1_General_CI_AS";
69 36 : sql = odbc_buf_asprintf(&odbc_buf, "SELECT CONVERT(%sTEXT,'Prova'%s + REPLICATE('x',500))%s", n_flag, collate, collate);
70 36 : odbc_command(sql);
71 :
72 36 : CHKFetch("S");
73 :
74 : /* these 2 tests test an old severe BUG in FreeTDS */
75 36 : buf = (char *) ODBC_GET(1);
76 36 : CHKGetData(1, type, buf, 0, &len, "I");
77 36 : if (len != SQL_NO_TOTAL)
78 18 : CheckLen(505*lc);
79 36 : CHKGetData(1, type, buf, 0, &len, "I");
80 36 : if (len != SQL_NO_TOTAL)
81 18 : CheckLen(505*lc);
82 36 : buf = (char *) ODBC_GET(3*lc);
83 36 : CHKGetData(1, type, buf, 3 * lc, &len, "I");
84 36 : if (len != SQL_NO_TOTAL)
85 18 : CheckLen(505*lc);
86 36 : if (mycmp(buf, "Pr") != 0) {
87 0 : printf("Wrong data result 1\n");
88 0 : exit(1);
89 : }
90 :
91 36 : buf = (char *) ODBC_GET(16*lc);
92 36 : CHKGetData(1, type, buf, 16 * lc, &len, "I");
93 36 : if (len != SQL_NO_TOTAL)
94 18 : CheckLen(503*lc);
95 36 : if (mycmp(buf, "ovaxxxxxxxxxxxx") != 0) {
96 0 : printf("Wrong data result 2 res = '%s'\n", buf);
97 0 : exit(1);
98 : }
99 :
100 36 : buf = (char *) ODBC_GET(256*lc);
101 36 : CHKGetData(1, type, buf, 256 * lc, &len, "I");
102 36 : if (len != SQL_NO_TOTAL)
103 18 : CheckLen(488*lc);
104 36 : CHKGetData(1, type, buf, 256 * lc, &len, "S");
105 36 : CheckLen(233*lc);
106 36 : CHKGetData(1, type, buf, 256 * lc, &len, "No");
107 :
108 36 : odbc_reset_statement();
109 :
110 : /* test with varchar, not blob but variable */
111 36 : sql = odbc_buf_asprintf(&odbc_buf, "SELECT CONVERT(%sVARCHAR(100), 'Other test')", n_flag);
112 36 : odbc_command(sql);
113 :
114 36 : CHKFetch("S");
115 :
116 36 : buf = (char *) ODBC_GET(7*lc);
117 36 : CHKGetData(1, type, buf, 7 * lc, NULL, "I");
118 36 : if (mycmp(buf, "Other ") != 0) {
119 0 : printf("Wrong data result 1\n");
120 0 : exit(1);
121 : }
122 :
123 36 : buf = (char *) ODBC_GET(5*lc);
124 36 : CHKGetData(1, type, buf, 20, NULL, "S");
125 36 : if (mycmp(buf, "test") != 0) {
126 0 : printf("Wrong data result 2 res = '%s'\n", buf);
127 0 : exit(1);
128 : }
129 36 : ODBC_FREE();
130 :
131 36 : odbc_reset_statement();
132 36 : }
133 :
134 10 : TEST_MAIN()
135 : {
136 : char buf[32];
137 : SQLINTEGER int_buf;
138 : SQLLEN len;
139 : SQLRETURN rc;
140 : TIMESTAMP_STRUCT tss;
141 :
142 10 : odbc_connect();
143 :
144 10 : lc = 1;
145 10 : type = SQL_C_CHAR;
146 10 : test_split("");
147 :
148 10 : lc = sizeof(SQLWCHAR);
149 10 : type = SQL_C_WCHAR;
150 10 : test_split("");
151 :
152 10 : if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x07000000u) {
153 8 : lc = 1;
154 8 : type = SQL_C_CHAR;
155 8 : test_split("N");
156 :
157 8 : lc = sizeof(SQLWCHAR);
158 8 : type = SQL_C_WCHAR;
159 8 : test_split("N");
160 : }
161 :
162 : /* test with fixed length */
163 10 : odbc_command("SELECT CONVERT(INT, 12345)");
164 :
165 10 : CHKFetch("S");
166 :
167 10 : int_buf = 0xdeadbeef;
168 10 : CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "S");
169 10 : if (int_buf != 12345) {
170 0 : printf("Wrong data result\n");
171 0 : exit(1);
172 : }
173 :
174 10 : CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "No");
175 10 : if (int_buf != 12345) {
176 0 : printf("Wrong data result 2 res = %d\n", (int) int_buf);
177 0 : exit(1);
178 : }
179 :
180 10 : odbc_reset_statement();
181 :
182 : /* test with numeric */
183 10 : odbc_command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)");
184 :
185 10 : CHKFetch("S");
186 :
187 10 : memset(buf, 'x', sizeof(buf));
188 10 : CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "S");
189 10 : buf[sizeof(buf)-1] = 0;
190 10 : if (strcmp(buf, "1850000000000") != 0) {
191 0 : printf("Wrong data result: %s\n", buf);
192 0 : exit(1);
193 : }
194 :
195 : /* should give NO DATA */
196 10 : CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "No");
197 10 : buf[sizeof(buf)-1] = 0;
198 10 : if (strcmp(buf, "1850000000000") != 0) {
199 0 : printf("Wrong data result 3 res = %s\n", buf);
200 0 : exit(1);
201 : }
202 :
203 10 : odbc_reset_statement();
204 :
205 :
206 : /* test int to truncated string */
207 10 : odbc_command("SELECT CONVERT(INTEGER, 12345)");
208 10 : CHKFetch("S");
209 :
210 : /* error 22003 */
211 10 : memset(buf, 'x', sizeof(buf));
212 10 : CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E");
213 : #ifdef ENABLE_DEVELOPING
214 : buf[4] = 0;
215 : if (strcmp(buf, "xxxx") != 0) {
216 : fprintf(stderr, "Wrong buffer result buf = %s\n", buf);
217 : exit(1);
218 : }
219 : #endif
220 10 : odbc_read_error();
221 10 : if (strcmp(odbc_sqlstate, "22003") != 0) {
222 0 : fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
223 0 : odbc_disconnect();
224 0 : exit(1);
225 : }
226 10 : CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
227 10 : odbc_reset_statement();
228 :
229 : /* test unique identifier to truncated string */
230 10 : rc = odbc_command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo");
231 10 : if (rc != SQL_ERROR) {
232 8 : CHKFetch("S");
233 :
234 : /* error 22003 */
235 8 : CHKGetData(1, SQL_C_CHAR, buf, 17, NULL, "E");
236 8 : odbc_read_error();
237 8 : if (strcmp(odbc_sqlstate, "22003") != 0) {
238 0 : fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
239 0 : odbc_disconnect();
240 0 : exit(1);
241 : }
242 8 : CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
243 : }
244 10 : odbc_reset_statement();
245 :
246 :
247 10 : odbc_disconnect();
248 :
249 10 : odbc_use_version3 = 1;
250 10 : odbc_connect();
251 :
252 : /* test error from SQLGetData */
253 : /* wrong constant, SQL_VARCHAR is invalid as C type */
254 10 : test_err("prova 123", SQL_VARCHAR, "HY003");
255 : /* use ARD but no ARD data column */
256 10 : test_err("prova 123", SQL_ARD_TYPE, "07009");
257 : /* wrong conversion, int */
258 10 : test_err("prova 123", SQL_C_LONG, "22018");
259 : /* wrong conversion, date */
260 10 : test_err("prova 123", SQL_C_TIMESTAMP, "22018");
261 : /* overflow */
262 10 : test_err("1234567890123456789", SQL_C_LONG, "22003");
263 :
264 : /* test datetime precision */
265 10 : odbc_command("SELECT CONVERT(DATETIME, '2018-08-15 12:34:56.007')");
266 :
267 10 : CHKFetch("S");
268 :
269 10 : memset(&tss, 'x', sizeof(tss));
270 10 : CHKGetData(1, SQL_C_TYPE_TIMESTAMP, &tss, sizeof(tss), NULL, "S");
271 10 : if (tss.fraction != 7000000) {
272 0 : printf("Wrong data result: %lu\n", (unsigned long) tss.fraction);
273 0 : exit(1);
274 : }
275 :
276 10 : odbc_reset_statement();
277 :
278 : /* test for empty string from mssql */
279 10 : if (odbc_db_is_microsoft()) {
280 8 : lc = 1;
281 8 : type = SQL_C_CHAR;
282 :
283 8 : for (;;) {
284 16 : void *buf = ODBC_GET(lc);
285 :
286 16 : odbc_command("SELECT CONVERT(TEXT,'' COLLATE Latin1_General_CI_AS)");
287 :
288 16 : CHKFetch("S");
289 :
290 16 : len = 1234;
291 16 : CHKGetData(1, type, buf, lc, &len, "S");
292 :
293 16 : if (len != 0) {
294 0 : fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
295 0 : return 1;
296 : }
297 :
298 16 : CHKGetData(1, type, buf, lc, NULL, "No");
299 16 : odbc_reset_statement();
300 16 : ODBC_FREE();
301 :
302 16 : buf = ODBC_GET(4096*lc);
303 :
304 16 : odbc_command("SELECT CONVERT(TEXT,'' COLLATE Latin1_General_CI_AS)");
305 :
306 16 : CHKFetch("S");
307 :
308 16 : len = 1234;
309 16 : CHKGetData(1, type, buf, lc*4096, &len, "S");
310 :
311 16 : if (len != 0) {
312 0 : fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
313 0 : return 1;
314 : }
315 :
316 16 : CHKGetData(1, type, buf, lc*4096, NULL, "No");
317 16 : odbc_reset_statement();
318 16 : ODBC_FREE();
319 :
320 16 : if (type != SQL_C_CHAR)
321 : break;
322 8 : lc = sizeof(SQLWCHAR);
323 8 : type = SQL_C_WCHAR;
324 : }
325 :
326 8 : odbc_command("SELECT CONVERT(TEXT,'' COLLATE Latin1_General_CI_AS)");
327 :
328 8 : CHKFetch("S");
329 :
330 8 : len = 1234;
331 8 : CHKGetData(1, SQL_C_BINARY, buf, 1, &len, "S");
332 :
333 8 : if (len != 0) {
334 0 : fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
335 0 : return 1;
336 : }
337 :
338 8 : CHKGetData(1, SQL_C_BINARY, buf, 1, NULL, "No");
339 : }
340 :
341 10 : odbc_disconnect();
342 :
343 10 : printf("Done.\n");
344 10 : return 0;
345 : }
|