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