Line data Source code
1 : /*
2 : * Purpose: this will test what is returned from a batch of queries, some that return rows and some that do not
3 : * This is related to a bug first identified in PHPs PDO library https://bugs.php.net/bug.php?id=72969
4 : * Functions: dbbind dbcmd dbcolname dberrhandle dbisopt dbmsghandle dbnextrow dbnumcols dbopen dbresults dbsetlogintime dbsqlexec dbuse
5 : */
6 :
7 : #include "common.h"
8 :
9 : int
10 8 : main(int argc, char **argv)
11 : {
12 : LOGINREC *login;
13 : DBPROCESS *dbproc;
14 : int i;
15 : DBINT erc;
16 :
17 : RETCODE results_retcode;
18 : int rowcount;
19 : int colcount;
20 : int row_retcode;
21 :
22 8 : set_malloc_options();
23 :
24 8 : read_login_info(argc, argv);
25 8 : if (argc > 1) {
26 0 : argc -= optind;
27 0 : argv += optind;
28 : }
29 :
30 8 : printf("Starting %s\n", argv[0]);
31 :
32 : /* Fortify_EnterScope(); */
33 8 : dbinit();
34 :
35 8 : dberrhandle(syb_err_handler);
36 8 : dbmsghandle(syb_msg_handler);
37 :
38 8 : printf("About to logon as \"%s\"\n", USER);
39 :
40 8 : login = dblogin();
41 8 : DBSETLPWD(login, PASSWORD);
42 8 : DBSETLUSER(login, USER);
43 8 : DBSETLAPP(login, "wf_dbresults");
44 :
45 8 : if (argc > 1) {
46 0 : printf("server and login timeout overrides (%s and %s) detected\n", argv[0], argv[1]);
47 0 : strcpy(SERVER, argv[0]);
48 0 : i = atoi(argv[1]);
49 0 : if (i) {
50 0 : i = dbsetlogintime(i);
51 0 : printf("dbsetlogintime returned %s.\n", (i == SUCCEED) ? "SUCCEED" : "FAIL");
52 : }
53 : }
54 :
55 8 : printf("About to open \"%s\"\n", SERVER);
56 :
57 8 : dbproc = dbopen(login, SERVER);
58 8 : if (!dbproc) {
59 0 : fprintf(stderr, "Unable to connect to %s\n", SERVER);
60 0 : return 1;
61 : }
62 8 : dbloginfree(login);
63 :
64 8 : printf("Using database \"%s\"\n", DATABASE);
65 8 : if (strlen(DATABASE)) {
66 8 : erc = dbuse(dbproc, DATABASE);
67 8 : assert(erc == SUCCEED);
68 : }
69 :
70 8 : sql_cmd(dbproc);
71 8 : dbsqlexec(dbproc);
72 8 : while (dbresults(dbproc) != NO_MORE_RESULTS) {
73 : /* nop */
74 : }
75 :
76 : /*
77 : * This test is written to simulate how dblib is used in PDO
78 : * functions are called in the same order they would be if doing
79 : * PDO::query followed by some number of PDO::statement->nextRowset
80 : */
81 :
82 : /*
83 : * First, call everything that happens in PDO::query
84 : * this will return the results of the CREATE TABLE statement
85 : */
86 8 : dbcancel(dbproc);
87 :
88 8 : printf("using sql_cmd\n");
89 8 : sql_cmd(dbproc);
90 8 : dbsqlexec(dbproc);
91 :
92 8 : results_retcode = dbresults(dbproc);
93 8 : rowcount = DBCOUNT(dbproc);
94 8 : colcount = dbnumcols(dbproc);
95 :
96 8 : printf("** CREATE TABLE **\n");
97 8 : printf("RETCODE: %d\n", results_retcode);
98 8 : printf("ROWCOUNT: %d\n", rowcount);
99 8 : printf("COLCOUNT: %d\n\n", colcount);
100 :
101 : /* check that the results correspond to the create table statement */
102 8 : assert(results_retcode == SUCCEED);
103 8 : assert(rowcount == -1);
104 8 : assert(colcount == 0);
105 :
106 : /* now simulate calling nextRowset() for each remaining statement in our batch */
107 :
108 : /*
109 : * INSERT
110 : */
111 8 : printf("** INSERT **\n");
112 :
113 : /* there shouldn't be any rows in this resultset yet, it's still from the CREATE TABLE */
114 8 : row_retcode = dbnextrow(dbproc);
115 8 : printf("dbnextrow retcode: %d\n", results_retcode);
116 8 : assert(row_retcode == NO_MORE_ROWS);
117 :
118 8 : results_retcode = dbresults(dbproc);
119 8 : rowcount = DBCOUNT(dbproc);
120 8 : colcount = dbnumcols(dbproc);
121 :
122 8 : printf("RETCODE: %d\n", results_retcode);
123 8 : printf("ROWCOUNT: %d\n", rowcount);
124 8 : printf("COLCOUNT: %d\n\n", colcount);
125 :
126 8 : assert(results_retcode == SUCCEED);
127 8 : assert(rowcount == 3);
128 8 : assert(colcount == 0);
129 :
130 : /*
131 : * SELECT
132 : */
133 8 : printf("** SELECT **\n");
134 :
135 : /* the rowset is still from the INSERT and should have no rows */
136 8 : row_retcode = dbnextrow(dbproc);
137 8 : printf("dbnextrow retcode: %d\n", results_retcode);
138 8 : assert(row_retcode == NO_MORE_ROWS);
139 :
140 8 : results_retcode = dbresults(dbproc);
141 8 : rowcount = DBCOUNT(dbproc);
142 8 : colcount = dbnumcols(dbproc);
143 :
144 8 : printf("RETCODE: %d\n", results_retcode);
145 8 : printf("ROWCOUNT: %d\n", rowcount);
146 8 : printf("COLCOUNT: %d\n\n", colcount);
147 :
148 8 : assert(results_retcode == SUCCEED);
149 8 : assert(rowcount == -1);
150 8 : assert(colcount == 1);
151 :
152 : /* now we expect to find three rows in the rowset */
153 8 : row_retcode = dbnextrow(dbproc);
154 8 : printf("dbnextrow retcode: %d\n", row_retcode);
155 8 : assert(row_retcode == REG_ROW);
156 8 : row_retcode = dbnextrow(dbproc);
157 8 : printf("dbnextrow retcode: %d\n", row_retcode);
158 8 : assert(row_retcode == REG_ROW);
159 8 : row_retcode = dbnextrow(dbproc);
160 8 : printf("dbnextrow retcode: %d\n\n", row_retcode);
161 8 : assert(row_retcode == REG_ROW);
162 :
163 : /*
164 : * UPDATE
165 : */
166 8 : printf("** UPDATE **\n");
167 :
168 : /* check that there are no rows left, then we'll get the results from the UPDATE */
169 8 : row_retcode = dbnextrow(dbproc);
170 8 : printf("dbnextrow retcode: %d\n", row_retcode);
171 8 : assert(row_retcode == NO_MORE_ROWS);
172 :
173 8 : results_retcode = dbresults(dbproc);
174 8 : rowcount = DBCOUNT(dbproc);
175 8 : colcount = dbnumcols(dbproc);
176 :
177 8 : printf("RETCODE: %d\n", results_retcode);
178 8 : printf("ROWCOUNT: %d\n", rowcount);
179 8 : printf("COLCOUNT: %d\n\n", colcount);
180 :
181 8 : assert(results_retcode == SUCCEED);
182 8 : assert(rowcount == 3);
183 : /*assert(colcount == 0); TODO: why does an update get a column? */
184 :
185 : /*
186 : * SELECT
187 : */
188 8 : printf("** SELECT **\n");
189 :
190 8 : row_retcode = dbnextrow(dbproc);
191 8 : printf("dbnextrow retcode: %d\n", row_retcode);
192 8 : assert(row_retcode == NO_MORE_ROWS);
193 :
194 8 : results_retcode = dbresults(dbproc);
195 8 : rowcount = DBCOUNT(dbproc);
196 8 : colcount = dbnumcols(dbproc);
197 :
198 8 : printf("RETCODE: %d\n", results_retcode);
199 8 : printf("ROWCOUNT: %d\n", rowcount);
200 8 : printf("COLCOUNT: %d\n\n", colcount);
201 :
202 8 : assert(results_retcode == SUCCEED);
203 8 : assert(rowcount == -1);
204 8 : assert(colcount == 1);
205 :
206 : /* now we expect to find three rows in the rowset again */
207 8 : row_retcode = dbnextrow(dbproc);
208 8 : printf("dbnextrow retcode: %d\n", row_retcode);
209 8 : assert(row_retcode == REG_ROW);
210 8 : row_retcode = dbnextrow(dbproc);
211 8 : printf("dbnextrow retcode: %d\n", row_retcode);
212 8 : assert(row_retcode == REG_ROW);
213 8 : row_retcode = dbnextrow(dbproc);
214 8 : printf("dbnextrow retcode: %d\n\n", row_retcode);
215 8 : assert(row_retcode == REG_ROW);
216 :
217 : /*
218 : * DROP
219 : */
220 8 : printf("** DROP **\n");
221 :
222 8 : row_retcode = dbnextrow(dbproc);
223 8 : printf("dbnextrow retcode: %d\n", row_retcode);
224 8 : assert(row_retcode == NO_MORE_ROWS);
225 :
226 8 : results_retcode = dbresults(dbproc);
227 8 : rowcount = DBCOUNT(dbproc);
228 8 : colcount = dbnumcols(dbproc);
229 :
230 8 : printf("RETCODE: %d\n", results_retcode);
231 8 : printf("ROWCOUNT: %d\n", rowcount);
232 8 : printf("COLCOUNT: %d\n\n", colcount);
233 :
234 8 : assert(results_retcode == SUCCEED);
235 8 : assert(rowcount == -1);
236 : /* assert(colcount == 0); */
237 :
238 : /* Call one more time to be sure we get NO_MORE_RESULTS */
239 8 : row_retcode = dbnextrow(dbproc);
240 8 : printf("dbnextrow retcode: %d\n", row_retcode);
241 8 : assert(row_retcode == NO_MORE_ROWS);
242 :
243 8 : results_retcode = dbresults(dbproc);
244 8 : rowcount = DBCOUNT(dbproc);
245 8 : colcount = dbnumcols(dbproc);
246 :
247 8 : printf("RETCODE: %d\n", results_retcode);
248 8 : printf("ROWCOUNT: %d\n", rowcount);
249 8 : printf("COLCOUNT: %d\n\n", colcount);
250 :
251 8 : assert(results_retcode == NO_MORE_RESULTS);
252 8 : assert(rowcount == -1);
253 : /* assert(colcount == 0); */
254 :
255 8 : dbexit();
256 :
257 8 : printf("%s OK\n", __FILE__);
258 8 : return 0;
259 : }
|