Line data Source code
1 : #include "common.h"
2 :
3 : static void
4 240 : TestName(int index, const char *expected_name)
5 : {
6 240 : ODBC_BUF *odbc_buf = NULL;
7 : SQLTCHAR name[128];
8 : char buf[256];
9 : SQLSMALLINT len, type;
10 :
11 : #define NAME_TEST \
12 : do { \
13 : if (strcmp(C(name), expected_name) != 0) \
14 : { \
15 : sprintf(buf, "wrong name in column %d expected '%s' got '%s'", index, expected_name, C(name)); \
16 : ODBC_REPORT_ERROR(buf); \
17 : } \
18 : } while(0)
19 :
20 : /* retrieve with SQLDescribeCol */
21 240 : CHKDescribeCol(index, name, TDS_VECTOR_SIZE(name), &len, &type, NULL, NULL, NULL, "S");
22 240 : NAME_TEST;
23 :
24 : /* retrieve with SQLColAttribute */
25 240 : CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
26 240 : if (odbc_db_is_microsoft())
27 180 : NAME_TEST;
28 240 : CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
29 240 : NAME_TEST;
30 240 : ODBC_FREE();
31 240 : }
32 :
33 : static void
34 84 : Flushodbc_stmt(void)
35 : {
36 84 : while (CHKFetch("SNo") == SQL_SUCCESS)
37 : ;
38 :
39 : /* Sybase store procedure seems to return extra empty results */
40 84 : while (CHKMoreResults("SNo") == SQL_SUCCESS)
41 : ;
42 84 : }
43 :
44 : static void
45 52 : CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int line)
46 : {
47 : SQLSMALLINT out_type;
48 : SQLLEN ind;
49 : SQLRETURN RetCode;
50 :
51 52 : printf("CheckType %d\n", line);
52 52 : CHKBindCol(2, SQL_C_SSHORT, &out_type, 0, &ind, "SI");
53 52 : CHKGetTypeInfo(type, "SI");
54 52 : RetCode = CHKFetch("SNo");
55 52 : switch (RetCode) {
56 44 : case SQL_SUCCESS:
57 44 : if (expected == SQL_UNKNOWN_TYPE) {
58 0 : fprintf(stderr, "Data not expected (type %d - %s) line %d\n", type, string_type, line);
59 0 : odbc_disconnect();
60 0 : exit(1);
61 : }
62 44 : if (expected != out_type) {
63 0 : fprintf(stderr, "Got type %d expected %d. Input type %d - %s line %d\n", out_type, expected, type, string_type, line);
64 0 : odbc_disconnect();
65 0 : exit(1);
66 : }
67 : break;
68 8 : case SQL_NO_DATA:
69 8 : if (expected != SQL_UNKNOWN_TYPE) {
70 0 : fprintf(stderr, "Data expected. Input type %d - %s line %d\n", type, string_type, line);
71 0 : odbc_disconnect();
72 0 : exit(1);
73 : }
74 : break;
75 : }
76 :
77 52 : SQLFreeStmt(odbc_stmt, SQL_UNBIND);
78 :
79 52 : Flushodbc_stmt();
80 52 : }
81 :
82 : static void
83 16 : DoTest(int version3)
84 : {
85 : char name[128], params[128];
86 : SQLSMALLINT type, is_unsigned;
87 : SQLINTEGER col_size, min_scale;
88 : SQLLEN ind1, ind2, ind3, ind4, ind5, ind6;
89 16 : int date_time_supported = 0;
90 : int name_version3;
91 : int tdsver;
92 :
93 16 : odbc_use_version3 = version3;
94 16 : name_version3 = version3;
95 :
96 16 : odbc_connect();
97 :
98 16 : printf("Using ODBC version %d\n", version3 ? 3 : 2);
99 :
100 16 : tdsver = odbc_tds_version();
101 :
102 : /* test column name */
103 : /* MS ODBC use always ODBC 3 names even in ODBC 2 mode */
104 16 : if (!odbc_driver_is_freetds())
105 0 : name_version3 = 1;
106 16 : CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
107 16 : TestName(1, "TYPE_NAME");
108 16 : TestName(2, "DATA_TYPE");
109 16 : TestName(3, name_version3 ? "COLUMN_SIZE" : "PRECISION");
110 16 : TestName(4, "LITERAL_PREFIX");
111 16 : TestName(5, "LITERAL_SUFFIX");
112 16 : TestName(6, "CREATE_PARAMS");
113 16 : TestName(7, "NULLABLE");
114 16 : TestName(8, "CASE_SENSITIVE");
115 16 : TestName(9, "SEARCHABLE");
116 16 : TestName(10, "UNSIGNED_ATTRIBUTE");
117 16 : TestName(11, name_version3 ? "FIXED_PREC_SCALE" : "MONEY");
118 16 : TestName(12, name_version3 ? "AUTO_UNIQUE_VALUE" : "AUTO_INCREMENT");
119 16 : TestName(13, "LOCAL_TYPE_NAME");
120 16 : TestName(14, "MINIMUM_SCALE");
121 16 : TestName(15, "MAXIMUM_SCALE");
122 :
123 : /* TODO test these column for ODBC 3 */
124 : /* ODBC 3.0 SQL_DATA_TYPE SQL_DATETIME_SUB NUM_PREC_RADIX INTERVAL_PRECISION */
125 :
126 16 : Flushodbc_stmt();
127 :
128 : /* TODO test if SQL_ALL_TYPES returns right numeric type for timestamp */
129 :
130 : /* numeric type for data */
131 :
132 : /* test for date/time support */
133 16 : if (odbc_command_with_result(odbc_stmt, "select cast(getdate() as date)") == SQL_SUCCESS)
134 8 : date_time_supported = 1;
135 16 : if (odbc_db_is_microsoft() && tdsver < 0x703)
136 8 : date_time_supported = 0;
137 16 : SQLCloseCursor(odbc_stmt);
138 :
139 : #define CHECK_TYPE(in,out) CheckType(in, out, #in, __LINE__)
140 :
141 : /* under Sybase this type require extra handling, check it */
142 16 : CHECK_TYPE(SQL_VARCHAR, SQL_VARCHAR);
143 :
144 16 : if (version3) {
145 : /* MS ODBC returns S1004 (HY004), TODO support it */
146 8 : CHECK_TYPE(SQL_TYPE_DATE, date_time_supported ? SQL_TYPE_DATE : SQL_UNKNOWN_TYPE);
147 8 : if (!odbc_db_is_microsoft())
148 2 : CHECK_TYPE(SQL_TYPE_TIME, date_time_supported ? SQL_TYPE_TIME : SQL_UNKNOWN_TYPE);
149 : /* MS ODBC returns S1004 (HY004), TODO support it */
150 8 : CHECK_TYPE(SQL_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP);
151 : } else {
152 8 : CHECK_TYPE(SQL_DATE, date_time_supported ? SQL_DATE : SQL_UNKNOWN_TYPE);
153 8 : if (!odbc_db_is_microsoft())
154 2 : CHECK_TYPE(SQL_TIME, date_time_supported ? SQL_TIME : SQL_UNKNOWN_TYPE);
155 : /* TODO MS ODBC handle SQL_TIMESTAMP even for ODBC 3 */
156 8 : CHECK_TYPE(SQL_TIMESTAMP, SQL_TIMESTAMP);
157 : }
158 :
159 : /* TODO implement this part of test */
160 : /* varchar/nvarchar before sysname */
161 :
162 : /* test binding (not all column, required for Oracle) */
163 16 : CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
164 16 : CHKBindCol(1, SQL_C_CHAR, name, sizeof(name), &ind1, "SI");
165 16 : CHKBindCol(2, SQL_C_SSHORT, &type, 0, &ind2, "SI");
166 16 : CHKBindCol(3, SQL_C_SLONG, &col_size, 0, &ind3, "SI");
167 16 : CHKBindCol(6, SQL_C_CHAR, params, sizeof(params), &ind4, "SI");
168 16 : CHKBindCol(10, SQL_C_SSHORT, &is_unsigned, 0, &ind5, "SI");
169 16 : CHKBindCol(14, SQL_C_SSHORT, &min_scale, 0, &ind6, "SI");
170 16 : while (CHKFetch("SNo") == SQL_SUCCESS)
171 : ;
172 16 : SQLFreeStmt(odbc_stmt, SQL_UNBIND);
173 16 : Flushodbc_stmt();
174 :
175 : /* check WVARCHAR for no pending data */
176 16 : if (odbc_db_is_microsoft() || strncmp(odbc_db_version(), "15.00.", 6) >= 0) {
177 16 : CHKGetTypeInfo(SQL_WVARCHAR, "SI");
178 16 : CHKFetch("S");
179 : /* mssql returns SYSNAME as NVARCHAR */
180 16 : if (odbc_db_is_microsoft())
181 12 : CHKFetch("S");
182 :
183 : /* mssql 2008 can return a lot of NVARCHAR as new type (ie DATE)
184 : * are converted automatically to NVARCHAR with former protocol
185 : */
186 16 : if (!odbc_db_is_microsoft() || tdsver >= 0x703 || odbc_db_version_int() < 0x0a000000)
187 16 : CHKFetch("No");
188 16 : CHKMoreResults("No");
189 :
190 16 : CHKGetTypeInfo(SQL_BINARY, "SI");
191 : }
192 :
193 16 : odbc_disconnect();
194 16 : }
195 :
196 : int
197 8 : main(int argc, char *argv[])
198 : {
199 8 : DoTest(0);
200 :
201 8 : DoTest(1);
202 :
203 8 : printf("Done.\n");
204 : return 0;
205 : }
|