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