1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
/*
* This test is used to check the output and processing of the catalog
* functions listed as below:
* - SQLGetTypeInfo
* - SQLTables
* - SQLColumns
* - SQLSpecialColumns
* - SQLStatistics
* - SQLPrimaryKeys
* - SQLForeignKeys
* - SQLProcedureColumns
* - SQLTablePrivileges
* - SQLColumnPrivileges
* - SQLProcedures
* - SQLGetInfo
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
/* define a macro to simplify function calls */
#define PRINT_RESULT_SERIES(hstmt, idarray, rowcount) print_result_series(hstmt, idarray, sizeof(idarray)/sizeof(idarray[0]), rowcount, FALSE)
int
main(int argc, char **argv)
{
int rc;
HSTMT hstmt = SQL_NULL_HSTMT;
/* Cases where output is limited to relevant information only */
SQLSMALLINT sql_tab_privileges_ids[6] = {1, 2, 3, 4, 6, 7};
SQLSMALLINT sql_column_privileges_ids[6] = {1, 2, 3, 4, 7, 8};
SQLSMALLINT sql_column_ids[6] = {1, 2, 3, 4, 5, 6};
SQLSMALLINT sql_pro_column_ids[] = {1, 2, 3, 4, 5, 6, 7};
char buf[1000];
char username[100];
SQLSMALLINT len;
int i;
test_connect();
rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
if (!SQL_SUCCEEDED(rc))
{
print_diag("failed to allocate stmt handle", SQL_HANDLE_DBC, conn);
exit(1);
}
SQLExecDirect(hstmt, (SQLCHAR *) "drop table if exists testtab2", SQL_NTS);
/* Check for SQLGetTypeInfo */
printf("Check for SQLTypeInfo\n");
rc = SQLGetTypeInfo(hstmt, SQL_VARCHAR);
CHECK_STMT_RESULT(rc, "SQLGetTypeInfo failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLTables */
printf("Check for SQLTables\n");
rc = SQLTables(hstmt, NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "%", SQL_NTS,
(SQLCHAR *) "TABLE", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLTables failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLColumns */
printf("Check for SQLColumns\n");
rc = SQLColumns(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "%", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLColumns failed", hstmt);
print_result_meta(hstmt);
/*
* Print only the 6 first columns, we do not want for example
* to get the OID in output, and this information looks to be
* enough.
*/
PRINT_RESULT_SERIES(hstmt, sql_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLColumnPrivileges */
printf("Check for SQLColumnPrivileges\n");
rc = SQLColumnPrivileges(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab1", SQL_NTS,
(SQLCHAR *) "id", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLColumnPrivileges failed", hstmt);
print_result_meta(hstmt);
PRINT_RESULT_SERIES(hstmt, sql_column_privileges_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLSpecialColumns */
printf("Check for SQLSpecialColumns\n");
rc = SQLSpecialColumns(hstmt, SQL_ROWVER,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab1", SQL_NTS,
SQL_SCOPE_SESSION,
SQL_NO_NULLS);
CHECK_STMT_RESULT(rc, "SQLSpecialColumns failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLStatistics. It is important to note that this function
* returns statistics like the number of pages used and the number of
* index scans.
*/
printf("Check for SQLStatistics\n");
rc = SQLStatistics(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab1", SQL_NTS,
0, 0);
CHECK_STMT_RESULT(rc, "SQLStatistics failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLPrimaryKeys */
printf("Check for SQLPrimaryKeys\n");
rc = SQLPrimaryKeys(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab1", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLPrimaryKeys failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLForeignKeys */
printf("Check for SQLForeignKeys\n");
rc = SQLForeignKeys(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab1", SQL_NTS,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "testtab_fk", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLForeignKeys failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLProcedures */
printf("Check for SQLProcedures\n");
rc = SQLProcedures(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "simple_add", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLProcedures failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLProcedureColumns */
printf("Check for SQLProcedureColumns\n");
rc = SQLProcedureColumns(hstmt,
NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "simple_add", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
print_result_meta(hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLProcedureColumns for a function
* returning normal type
*/
rc = SQLProcedureColumns(hstmt, NULL, 0,
NULL, 0,
(SQLCHAR *) "set_byte", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
PRINT_RESULT_SERIES(hstmt, sql_pro_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLProcedureColumns for a function
* returning composite type
*/
rc = SQLProcedureColumns(hstmt, NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "getfoo", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
PRINT_RESULT_SERIES(hstmt, sql_pro_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLProcedureColumns for a function
* returning setof composite type
*/
rc = SQLProcedureColumns(hstmt, NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "getboo", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
PRINT_RESULT_SERIES(hstmt, sql_pro_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLProcedureColumns for a function
* returning table
*/
rc = SQLProcedureColumns(hstmt, NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "tbl_arg", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
PRINT_RESULT_SERIES(hstmt, sql_pro_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check for SQLProcedureColumns for a function with OUT
* parameters returning setof
* This is equivalent to tbl_arg.
*/
rc = SQLProcedureColumns(hstmt, NULL, 0,
(SQLCHAR *) "public", SQL_NTS,
(SQLCHAR *) "set_of", SQL_NTS,
NULL, 0);
CHECK_STMT_RESULT(rc, "SQLProcedureColumns failed", hstmt);
PRINT_RESULT_SERIES(hstmt, sql_pro_column_ids, -1);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Check for SQLTablePrivileges */
printf("Check for SQLTablePrivileges\n");
rc = SQLTablePrivileges(hstmt,
NULL, 0,
(SQLCHAR *) "public", 0,
(SQLCHAR *) "testtab1", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLTablePrivileges failed", hstmt);
print_result_meta(hstmt);
PRINT_RESULT_SERIES(hstmt, sql_tab_privileges_ids, 5);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Test SQLGetInfo */
printf("Check for SQLGetInfo\n");
rc = SQLGetInfo(conn, SQL_TABLE_TERM, buf, sizeof(buf), &len);
CHECK_STMT_RESULT(rc, "SQLGetInfo failed", hstmt);
printf("Term for \"table\": %s\n", buf);
/****
* Misc extra tests.
*/
/*
* Older versions of the driver had a bug in handling table-types lists
* longer than 32 entries. Check for that.
*/
rc = SQLTables(hstmt, "", SQL_NTS,
"public", SQL_NTS,
"testtab%", SQL_NTS,
"1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5,6,7,8,9,0,1,2,3,4,5, TABLES", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLTables failed", hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Older versions of the driver had a buffer overflow bug in handling table
* patterns with lots of escapes, with standard_conforming_strings=off.
* Check for that.
*/
for (i = 0; i < sizeof(buf) - 1; i++)
buf[i] = '\\';
buf[i] = '\0';
rc = SQLTables(hstmt, "", SQL_NTS,
"public", SQL_NTS,
buf, SQL_NTS,
"TABLES", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLTables failed", hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/*
* Check that things work with an invalid search_path. current_schema()
* returns NULL in that case, which used to cause a segfault.
*
* Perform these tests in a fresh connection, so that we don't use a
* cached current_schema value.
*/
test_disconnect();
test_connect();
rc = SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
CHECK_CONN_RESULT(rc, "failed to allocate stmt handle", conn);
rc = SQLExecDirect(hstmt, (SQLCHAR *) "set search_path='bogus_schema'", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLExecDirect failed", hstmt);
rc = SQLGetInfo(conn, SQL_USER_NAME, username, sizeof(username), &len);
CHECK_STMT_RESULT(rc, "SQLGetInfo failed", hstmt);
rc = SQLTables(hstmt, "", SQL_NTS,
username, SQL_NTS,
"testtab%", SQL_NTS,
"", SQL_NTS);
CHECK_STMT_RESULT(rc, "SQLTables failed", hstmt);
print_result(hstmt);
rc = SQLFreeStmt(hstmt, SQL_CLOSE);
CHECK_STMT_RESULT(rc, "SQLFreeStmt failed", hstmt);
/* Clean up */
test_disconnect();
return 0;
}
|