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: 2024-03-23 08:24:27 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           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, "batch_stmt_ins_sel");
      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             : }

Generated by: LCOV version 1.13