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 10 : 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 10 : set_malloc_options();
23 :
24 10 : read_login_info(argc, argv);
25 10 : if (argc > 1) {
26 0 : argc -= optind;
27 0 : argv += optind;
28 : }
29 :
30 10 : printf("Starting %s\n", argv[0]);
31 :
32 : /* Fortify_EnterScope(); */
33 10 : dbinit();
34 :
35 10 : dberrhandle(syb_err_handler);
36 10 : dbmsghandle(syb_msg_handler);
37 :
38 10 : printf("About to logon as \"%s\"\n", USER);
39 :
40 10 : login = dblogin();
41 10 : DBSETLPWD(login, PASSWORD);
42 10 : DBSETLUSER(login, USER);
43 10 : DBSETLAPP(login, "batch_stmt_ins_sel");
44 :
45 10 : 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 10 : printf("About to open \"%s\"\n", SERVER);
56 :
57 10 : dbproc = dbopen(login, SERVER);
58 10 : if (!dbproc) {
59 0 : fprintf(stderr, "Unable to connect to %s\n", SERVER);
60 0 : return 1;
61 : }
62 10 : dbloginfree(login);
63 :
64 10 : printf("Using database \"%s\"\n", DATABASE);
65 10 : if (strlen(DATABASE)) {
66 10 : erc = dbuse(dbproc, DATABASE);
67 10 : assert(erc == SUCCEED);
68 : }
69 :
70 10 : sql_cmd(dbproc);
71 10 : dbsqlexec(dbproc);
72 10 : 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 10 : dbcancel(dbproc);
87 :
88 10 : printf("using sql_cmd\n");
89 10 : sql_cmd(dbproc);
90 10 : dbsqlexec(dbproc);
91 :
92 10 : results_retcode = dbresults(dbproc);
93 10 : rowcount = DBCOUNT(dbproc);
94 10 : colcount = dbnumcols(dbproc);
95 :
96 10 : printf("** CREATE TABLE **\n");
97 10 : printf("RETCODE: %d\n", results_retcode);
98 10 : printf("ROWCOUNT: %d\n", rowcount);
99 10 : printf("COLCOUNT: %d\n\n", colcount);
100 :
101 : /* check that the results correspond to the create table statement */
102 10 : assert(results_retcode == SUCCEED);
103 10 : assert(rowcount == -1);
104 10 : assert(colcount == 0);
105 :
106 : /* now simulate calling nextRowset() for each remaining statement in our batch */
107 :
108 : /*
109 : * INSERT
110 : */
111 10 : printf("** INSERT **\n");
112 :
113 : /* there shouldn't be any rows in this resultset yet, it's still from the CREATE TABLE */
114 10 : row_retcode = dbnextrow(dbproc);
115 10 : printf("dbnextrow retcode: %d\n", results_retcode);
116 10 : assert(row_retcode == NO_MORE_ROWS);
117 :
118 10 : results_retcode = dbresults(dbproc);
119 10 : rowcount = DBCOUNT(dbproc);
120 10 : colcount = dbnumcols(dbproc);
121 :
122 10 : printf("RETCODE: %d\n", results_retcode);
123 10 : printf("ROWCOUNT: %d\n", rowcount);
124 10 : printf("COLCOUNT: %d\n\n", colcount);
125 :
126 10 : assert(results_retcode == SUCCEED);
127 10 : assert(rowcount == 3);
128 10 : assert(colcount == 0);
129 :
130 : /*
131 : * SELECT
132 : */
133 10 : printf("** SELECT **\n");
134 :
135 : /* the rowset is still from the INSERT and should have no rows */
136 10 : row_retcode = dbnextrow(dbproc);
137 10 : printf("dbnextrow retcode: %d\n", results_retcode);
138 10 : assert(row_retcode == NO_MORE_ROWS);
139 :
140 10 : results_retcode = dbresults(dbproc);
141 10 : rowcount = DBCOUNT(dbproc);
142 10 : colcount = dbnumcols(dbproc);
143 :
144 10 : printf("RETCODE: %d\n", results_retcode);
145 10 : printf("ROWCOUNT: %d\n", rowcount);
146 10 : printf("COLCOUNT: %d\n\n", colcount);
147 :
148 10 : assert(results_retcode == SUCCEED);
149 10 : assert(rowcount == -1);
150 10 : assert(colcount == 1);
151 :
152 : /* now we expect to find three rows in the rowset */
153 10 : row_retcode = dbnextrow(dbproc);
154 10 : printf("dbnextrow retcode: %d\n", row_retcode);
155 10 : assert(row_retcode == REG_ROW);
156 10 : row_retcode = dbnextrow(dbproc);
157 10 : printf("dbnextrow retcode: %d\n", row_retcode);
158 10 : assert(row_retcode == REG_ROW);
159 10 : row_retcode = dbnextrow(dbproc);
160 10 : printf("dbnextrow retcode: %d\n\n", row_retcode);
161 10 : assert(row_retcode == REG_ROW);
162 :
163 : /*
164 : * UPDATE
165 : */
166 10 : printf("** UPDATE **\n");
167 :
168 : /* check that there are no rows left, then we'll get the results from the UPDATE */
169 10 : row_retcode = dbnextrow(dbproc);
170 10 : printf("dbnextrow retcode: %d\n", row_retcode);
171 10 : assert(row_retcode == NO_MORE_ROWS);
172 :
173 10 : results_retcode = dbresults(dbproc);
174 10 : rowcount = DBCOUNT(dbproc);
175 10 : colcount = dbnumcols(dbproc);
176 :
177 10 : printf("RETCODE: %d\n", results_retcode);
178 10 : printf("ROWCOUNT: %d\n", rowcount);
179 10 : printf("COLCOUNT: %d\n\n", colcount);
180 :
181 10 : assert(results_retcode == SUCCEED);
182 10 : assert(rowcount == 3);
183 : /*assert(colcount == 0); TODO: why does an update get a column? */
184 :
185 : /*
186 : * SELECT
187 : */
188 10 : printf("** SELECT **\n");
189 :
190 10 : row_retcode = dbnextrow(dbproc);
191 10 : printf("dbnextrow retcode: %d\n", row_retcode);
192 10 : assert(row_retcode == NO_MORE_ROWS);
193 :
194 10 : results_retcode = dbresults(dbproc);
195 10 : rowcount = DBCOUNT(dbproc);
196 10 : colcount = dbnumcols(dbproc);
197 :
198 10 : printf("RETCODE: %d\n", results_retcode);
199 10 : printf("ROWCOUNT: %d\n", rowcount);
200 10 : printf("COLCOUNT: %d\n\n", colcount);
201 :
202 10 : assert(results_retcode == SUCCEED);
203 10 : assert(rowcount == -1);
204 10 : assert(colcount == 1);
205 :
206 : /* now we expect to find three rows in the rowset again */
207 10 : row_retcode = dbnextrow(dbproc);
208 10 : printf("dbnextrow retcode: %d\n", row_retcode);
209 10 : assert(row_retcode == REG_ROW);
210 10 : row_retcode = dbnextrow(dbproc);
211 10 : printf("dbnextrow retcode: %d\n", row_retcode);
212 10 : assert(row_retcode == REG_ROW);
213 10 : row_retcode = dbnextrow(dbproc);
214 10 : printf("dbnextrow retcode: %d\n\n", row_retcode);
215 10 : assert(row_retcode == REG_ROW);
216 :
217 : /*
218 : * DROP
219 : */
220 10 : printf("** DROP **\n");
221 :
222 10 : row_retcode = dbnextrow(dbproc);
223 10 : printf("dbnextrow retcode: %d\n", row_retcode);
224 10 : assert(row_retcode == NO_MORE_ROWS);
225 :
226 10 : results_retcode = dbresults(dbproc);
227 10 : rowcount = DBCOUNT(dbproc);
228 10 : colcount = dbnumcols(dbproc);
229 :
230 10 : printf("RETCODE: %d\n", results_retcode);
231 10 : printf("ROWCOUNT: %d\n", rowcount);
232 10 : printf("COLCOUNT: %d\n\n", colcount);
233 :
234 10 : assert(results_retcode == SUCCEED);
235 10 : assert(rowcount == -1);
236 : /* assert(colcount == 0); */
237 :
238 : /* Call one more time to be sure we get NO_MORE_RESULTS */
239 10 : row_retcode = dbnextrow(dbproc);
240 10 : printf("dbnextrow retcode: %d\n", row_retcode);
241 10 : assert(row_retcode == NO_MORE_ROWS);
242 :
243 10 : results_retcode = dbresults(dbproc);
244 10 : rowcount = DBCOUNT(dbproc);
245 10 : colcount = dbnumcols(dbproc);
246 :
247 10 : printf("RETCODE: %d\n", results_retcode);
248 10 : printf("ROWCOUNT: %d\n", rowcount);
249 10 : printf("COLCOUNT: %d\n\n", colcount);
250 :
251 10 : assert(results_retcode == NO_MORE_RESULTS);
252 10 : assert(rowcount == -1);
253 : /* assert(colcount == 0); */
254 :
255 10 : dbexit();
256 :
257 10 : printf("%s OK\n", __FILE__);
258 10 : return 0;
259 : }
|