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