LCOV - code coverage report
Current view: top level - src/dblib/unittests - batch_stmt_ins_sel.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 134 144 93.1 %
Date: 2025-02-21 09:36:06 Functions: 1 1 100.0 %

          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             : }

Generated by: LCOV version 1.13