1 /* test win64 consistency */
2 #include "common.h"
3
4 /*
5 set ipd processed_ptr with
6 SQLParamOptions/SQLSetDescField/SQL_ATTR_PARAMS_PROCESSED_PTR
7 check always same value IPD->processed_ptr attr
8 */
9
10 static void
prepare_something(void)11 prepare_something(void)
12 {
13 /* Some DM requires something to be prepared, so do it */
14 #ifndef TDS_NO_DM
15 CHKPrepare(T("select * from #tmp1"), SQL_NTS, "S");
16 #endif
17 }
18
19 static void
check_ipd_params(void)20 check_ipd_params(void)
21 {
22 void *ptr, *ptr2;
23 SQLHDESC desc;
24 SQLINTEGER ind;
25
26 CHKGetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR, &ptr, sizeof(ptr), NULL, "S");
27
28 /* get IPD */
29 CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
30
31 CHKR2(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind),
32 SQL_HANDLE_DESC, desc, "S");
33
34 if (ptr != ptr2) {
35 fprintf(stderr, "IPD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
36 exit(1);
37 }
38 }
39
40 static void
set_ipd_params1(SQLULEN * ptr)41 set_ipd_params1(SQLULEN *ptr)
42 {
43 CHKSetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR, ptr, 0, "S");
44 }
45
46 static void
set_ipd_params2(SQLULEN * ptr)47 set_ipd_params2(SQLULEN *ptr)
48 {
49 SQLHDESC desc;
50 SQLINTEGER ind;
51
52 /* get IPD */
53 CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
54
55 CHKR2(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0),
56 SQL_HANDLE_DESC, desc, "S");
57 }
58
59 static void
set_ipd_params3(SQLULEN * ptr)60 set_ipd_params3(SQLULEN *ptr)
61 {
62 CHKParamOptions(2, ptr, "S");
63 }
64
65 typedef void (*rows_set_t)(SQLULEN*);
66
67 static const rows_set_t param_set[] = {
68 set_ipd_params1,
69 set_ipd_params2,
70 set_ipd_params3,
71 NULL
72 };
73
74 #define MALLOC_N(t, n) (t*) malloc(n*sizeof(t))
75
76 static void
test_params(void)77 test_params(void)
78 {
79 #define ARRAY_SIZE 2
80 const rows_set_t *p;
81 SQLULEN len;
82 SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE);
83 SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE);
84 unsigned long int h, l;
85 unsigned int n;
86
87 prepare_something();
88
89 for (n = 0; n < ARRAY_SIZE; ++n) {
90 ids[n] = n;
91 id_lens[n] = 0;
92 }
93
94 /* test setting just some test pointers */
95 set_ipd_params1((SQLULEN *) TDS_INT2PTR(0x01020304));
96 check_ipd_params();
97 set_ipd_params2((SQLULEN *) TDS_INT2PTR(0xabcdef12));
98 check_ipd_params();
99 set_ipd_params3((SQLULEN *) TDS_INT2PTR(0x87654321));
100 check_ipd_params();
101
102 /* now see results */
103 for (p = param_set; *p != NULL; ++p) {
104 odbc_reset_statement();
105 len = 0xdeadbeef;
106 len <<= 16;
107 len <<= 16;
108 len |= 12345678;
109
110 (*p)(&len);
111 check_ipd_params();
112
113 CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) TDS_INT2PTR(ARRAY_SIZE), 0, "S");
114 CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
115
116 odbc_command("INSERT INTO #tmp1(i) VALUES(?)");
117 SQLMoreResults(odbc_stmt);
118 for (n = 0; n < ARRAY_SIZE; ++n)
119 SQLMoreResults(odbc_stmt);
120 l = (unsigned long int) (len & 0xfffffffflu);
121 len >>= 16;
122 h = (unsigned long int) (len >> 16);
123 if (h != 0 || l != 2) {
124 fprintf(stderr, "Wrong number returned in param rows high %lu low %lu\n", h, l);
125 exit(1);
126 }
127 }
128
129 free(ids);
130 free(id_lens);
131 }
132
133 /*
134 set ird processed_ptr with
135 SQLExtendedFetch/SQLSetDescField/SQL_ATTR_ROWS_FETCHED_PTR
136 check always same value IRD->processed_ptr attr
137 */
138
139 static void
check_ird_params(void)140 check_ird_params(void)
141 {
142 void *ptr, *ptr2;
143 SQLHDESC desc;
144 SQLINTEGER ind;
145
146 CHKGetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &ptr, sizeof(ptr), NULL, "S");
147
148 /* get IRD */
149 CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
150
151 CHKR2(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind),
152 SQL_HANDLE_DESC, desc, "S");
153
154 if (ptr != ptr2) {
155 fprintf(stderr, "IRD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
156 exit(1);
157 }
158 }
159
160 static void
set_ird_params1(SQLULEN * ptr)161 set_ird_params1(SQLULEN *ptr)
162 {
163 CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, ptr, 0, "S");
164 }
165
166 static void
set_ird_params2(SQLULEN * ptr)167 set_ird_params2(SQLULEN *ptr)
168 {
169 SQLHDESC desc;
170 SQLINTEGER ind;
171
172 /* get IRD */
173 CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
174
175 CHKR2(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0),
176 SQL_HANDLE_DESC, desc, "S");
177 }
178
179 static const rows_set_t row_set[] = {
180 set_ird_params1,
181 set_ird_params2,
182 NULL
183 };
184
185 #define MALLOC_N(t, n) (t*) malloc(n*sizeof(t))
186
187 static void
test_rows(void)188 test_rows(void)
189 {
190 const rows_set_t *p;
191 SQLULEN len;
192 SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE);
193 SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE);
194 unsigned long int h, l;
195 unsigned int n;
196
197 prepare_something();
198
199 for (n = 0; n < ARRAY_SIZE; ++n) {
200 ids[n] = n;
201 id_lens[n] = 0;
202 }
203
204 /* test setting just some test pointers */
205 set_ird_params1((SQLULEN *) TDS_INT2PTR(0x01020304));
206 check_ird_params();
207 set_ird_params2((SQLULEN *) TDS_INT2PTR(0xabcdef12));
208 check_ird_params();
209
210 /* now see results */
211 for (p = row_set; ; ++p) {
212 const char *test_name = NULL;
213
214 odbc_reset_statement();
215 prepare_something();
216 len = 0xdeadbeef;
217 len <<= 16;
218 len <<= 16;
219 len |= 12345678;
220 if (*p)
221 (*p)(&len);
222 check_ird_params();
223
224 #if 0
225 CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) TDS_INT2PTR(ARRAY_SIZE), 0, "S");
226 CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
227 #endif
228
229 CHKBindCol(1, SQL_C_ULONG, ids, 0, id_lens, "S");
230 if (*p) {
231 CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) TDS_INT2PTR(ARRAY_SIZE), 0, "S");
232
233 odbc_command("SELECT DISTINCT i FROM #tmp1");
234 SQLFetch(odbc_stmt);
235 test_name = "SQLSetStmtAttr";
236 } else {
237 CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) TDS_INT2PTR(ARRAY_SIZE), 0, "S");
238 odbc_command("SELECT DISTINCT i FROM #tmp1");
239 CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S");
240 test_name = "SQLExtendedFetch";
241 }
242 SQLMoreResults(odbc_stmt);
243
244 l = (unsigned long int) (len & 0xfffffffflu);
245 len >>= 16;
246 h = (unsigned long int) (len >> 16);
247 if (h != 0 || l != 2) {
248 fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx) test %s\n", h, h, l, l, test_name);
249 exit(1);
250 }
251
252 if (!*p)
253 break;
254 }
255
256 free(ids);
257 free(id_lens);
258 }
259
260 int
main(void)261 main(void)
262 {
263 if (sizeof(SQLLEN) != 8) {
264 printf("Not possible for this platform.\n");
265 odbc_test_skipped();
266 return 0;
267 }
268
269 odbc_use_version3 = 1;
270 odbc_connect();
271
272 odbc_command("create table #tmp1 (i int)");
273
274 test_params();
275 test_rows();
276
277 odbc_disconnect();
278 printf("Done\n");
279 return 0;
280 }
281
282