Line data Source code
1 : #include "common.h"
2 : #include <assert.h>
3 :
4 : struct type
5 : {
6 : SQLSMALLINT type;
7 : const char *name;
8 : unsigned flags;
9 : };
10 :
11 : #define FLAG_C 1
12 : #define FLAG_SQL 2
13 :
14 : #define TYPE_C(s) {s, #s, FLAG_C }
15 : #define TYPE_SQL(s) {s, #s, FLAG_SQL }
16 : #define TYPE_BOTH(s,s2) {s, #s, FLAG_SQL|FLAG_C }
17 : /*
18 : * Same define with test for constants
19 : * #define TYPE_BOTH(s,s2) {s, #s, (FLAG_SQL|FLAG_C)+((1/!(s-s2))-1) }
20 : */
21 : static const struct type types[] = {
22 : TYPE_BOTH(SQL_C_CHAR, SQL_CHAR),
23 : TYPE_BOTH(SQL_C_LONG, SQL_INTEGER),
24 : TYPE_BOTH(SQL_C_SHORT, SQL_SMALLINT),
25 : TYPE_BOTH(SQL_C_FLOAT, SQL_REAL),
26 : TYPE_BOTH(SQL_C_DOUBLE, SQL_DOUBLE),
27 : TYPE_BOTH(SQL_C_NUMERIC, SQL_NUMERIC),
28 : TYPE_C(SQL_C_DEFAULT),
29 : TYPE_C(SQL_C_DATE),
30 : TYPE_C(SQL_C_TIME),
31 : /* MS ODBC do not support SQL_TIMESTAMP for IPD type while we support it */
32 : /* TYPE_C(SQL_C_TIMESTAMP), */
33 : TYPE_BOTH(SQL_C_TIMESTAMP, SQL_TIMESTAMP),
34 : TYPE_BOTH(SQL_C_TYPE_DATE, SQL_TYPE_DATE),
35 : TYPE_BOTH(SQL_C_TYPE_TIME, SQL_TYPE_TIME),
36 : TYPE_BOTH(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP),
37 : TYPE_C(SQL_C_INTERVAL_YEAR),
38 : TYPE_C(SQL_C_INTERVAL_MONTH),
39 : TYPE_C(SQL_C_INTERVAL_DAY),
40 : TYPE_C(SQL_C_INTERVAL_HOUR),
41 : TYPE_C(SQL_C_INTERVAL_MINUTE),
42 : TYPE_C(SQL_C_INTERVAL_SECOND),
43 : TYPE_C(SQL_C_INTERVAL_YEAR_TO_MONTH),
44 : TYPE_C(SQL_C_INTERVAL_DAY_TO_HOUR),
45 : TYPE_C(SQL_C_INTERVAL_DAY_TO_MINUTE),
46 : TYPE_C(SQL_C_INTERVAL_DAY_TO_SECOND),
47 : TYPE_C(SQL_C_INTERVAL_HOUR_TO_MINUTE),
48 : TYPE_C(SQL_C_INTERVAL_HOUR_TO_SECOND),
49 : TYPE_C(SQL_C_INTERVAL_MINUTE_TO_SECOND),
50 : TYPE_BOTH(SQL_C_BINARY, SQL_BINARY),
51 : TYPE_BOTH(SQL_C_BIT, SQL_BIT),
52 : TYPE_C(SQL_C_SBIGINT),
53 : TYPE_C(SQL_C_UBIGINT),
54 : TYPE_BOTH(SQL_C_TINYINT, SQL_TINYINT),
55 : TYPE_C(SQL_C_SLONG),
56 : TYPE_C(SQL_C_SSHORT),
57 : TYPE_C(SQL_C_STINYINT),
58 : TYPE_C(SQL_C_ULONG),
59 : TYPE_C(SQL_C_USHORT),
60 : TYPE_C(SQL_C_UTINYINT),
61 : TYPE_BOTH(SQL_C_GUID, SQL_GUID),
62 :
63 : TYPE_SQL(SQL_BIGINT),
64 : TYPE_SQL(SQL_VARBINARY),
65 : TYPE_SQL(SQL_LONGVARBINARY),
66 : TYPE_SQL(SQL_VARCHAR),
67 : TYPE_SQL(SQL_LONGVARCHAR),
68 : TYPE_SQL(SQL_DECIMAL),
69 : TYPE_SQL(SQL_FLOAT),
70 : {0, NULL}
71 : };
72 :
73 : static const char *
74 : get_type_name(SQLSMALLINT type)
75 : {
76 590 : const struct type *p = types;
77 :
78 21810 : for (; p->name; ++p)
79 22990 : if (p->type == type)
80 : return p->name;
81 : return "(unknown)";
82 : }
83 :
84 : static int result = 0;
85 :
86 : static void
87 : check_msg(int check, const char *msg)
88 : {
89 900 : if (check)
90 : return;
91 0 : fprintf(stderr, "Check failed: %s\n", msg);
92 0 : result = 1;
93 : }
94 :
95 10 : TEST_MAIN()
96 : {
97 : const struct type *p;
98 : char buf[16];
99 : SQLINTEGER ind;
100 : SQLLEN lind;
101 : SQLHDESC desc;
102 :
103 10 : odbc_connect();
104 :
105 : /*
106 : * test setting two time a descriptor
107 : * success all user allocated are ARD or APD so type cheching can be done
108 : * TODO freeing descriptor dissociate it from statements
109 : */
110 :
111 : /* test C types */
112 460 : for (p = types; p->name; ++p) {
113 450 : if (SQL_SUCCEEDED
114 : (SQLBindParameter(odbc_stmt, 1, SQL_PARAM_INPUT, p->type, SQL_VARCHAR, (SQLUINTEGER) (-1), 0, buf, 16, &lind))) {
115 : SQLSMALLINT concise_type, type, code;
116 : SQLHDESC desc;
117 :
118 380 : concise_type = type = code = 0;
119 :
120 : /* get APD */
121 380 : SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
122 :
123 380 : CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
124 380 : CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
125 380 : CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
126 1140 : printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
127 : p->name, (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
128 760 : check_msg(p->flags & FLAG_C, "Type not C successed to be set in APD");
129 : } else {
130 : SQLSMALLINT concise_type, type, code;
131 : SQLHDESC desc;
132 :
133 70 : concise_type = type = code = 0;
134 :
135 70 : fprintf(stderr, "Error setting type %d (%s)\n", (int) p->type, p->name);
136 :
137 70 : concise_type = p->type;
138 70 : SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
139 70 : if (SQL_SUCCEEDED
140 : (SQLSetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, TDS_INT2PTR(concise_type), sizeof(SQLSMALLINT))))
141 : {
142 0 : CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
143 0 : CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
144 0 : CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
145 0 : printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
146 : p->name,
147 : (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
148 0 : check_msg(p->flags & FLAG_C, "Type not C successed to be set in APD");
149 : } else {
150 70 : check_msg(!(p->flags & FLAG_C), "Type C failed to be set in APD");
151 : }
152 : }
153 : }
154 :
155 10 : printf("\n\n");
156 :
157 : /* test SQL types */
158 10 : SQLGetStmtAttr(odbc_stmt, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind);
159 460 : for (p = types; p->name; ++p) {
160 450 : SQLSMALLINT concise_type = p->type;
161 :
162 450 : if (SQL_SUCCEEDED
163 : (SQLSetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, TDS_INT2PTR(concise_type), sizeof(SQLSMALLINT)))) {
164 : SQLSMALLINT concise_type, type, code;
165 :
166 210 : concise_type = type = code = 0;
167 :
168 210 : CHKGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind, "S");
169 210 : CHKGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind, "S");
170 210 : CHKGetDescField(desc, 1, SQL_DESC_DATETIME_INTERVAL_CODE, &code, sizeof(SQLSMALLINT), &ind, "S");
171 630 : printf("Setted type %s -> [%d (%s), %d (%s), %d]\n",
172 : p->name, (int) concise_type, get_type_name(concise_type), (int) type, get_type_name(type), code);
173 420 : check_msg(p->flags & FLAG_SQL, "Type not SQL successed to be set in IPD");
174 : } else {
175 240 : fprintf(stderr, "Error setting type %d (%s)\n", (int) p->type, p->name);
176 240 : check_msg(!(p->flags & FLAG_SQL), "Type SQL failed to be set in IPD");
177 : }
178 : }
179 :
180 10 : odbc_disconnect();
181 :
182 10 : return result;
183 : }
|