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: 132 134 98.5 %
Date: 2025-04-21 16:22: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          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             : }

Generated by: LCOV version 1.13