LCOV - code coverage report
Current view: top level - src/odbc/unittests - compute.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 91 96 94.8 %
Date: 2025-04-21 03:58:01 Functions: 3 3 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : #include <assert.h>
       3             : 
       4             : /* Test compute results */
       5             : 
       6             : /*
       7             :  * This it's quite important cause it test different result types
       8             :  * mssql odbc have also some extension not supported by FreeTDS
       9             :  * and declared in odbcss.h
      10             :  */
      11             : 
      12             : static char col1[256], col2[256];
      13             : static SQLLEN ind1, ind2;
      14             : 
      15             : static int main_line;
      16             : 
      17             : static void
      18         128 : TestName(SQLSMALLINT index, const char *expected_name)
      19             : {
      20             :         SQLTCHAR name[128];
      21             :         char buf[256];
      22             :         SQLSMALLINT len, type;
      23             : 
      24             : #define NAME_TEST \
      25             :         do { \
      26             :                 if (strcmp(C(name), expected_name) != 0) \
      27             :                 { \
      28             :                         sprintf(buf, "line %d: wrong name in column %d expected '%s' got '%s'", \
      29             :                                 main_line, index, expected_name, C(name)); \
      30             :                         ODBC_REPORT_ERROR(buf); \
      31             :                 } \
      32             :         } while(0)
      33             : 
      34             :         /* retrieve with SQLDescribeCol */
      35         128 :         CHKDescribeCol(index, name, TDS_VECTOR_SIZE(name), &len, &type, NULL, NULL, NULL, "S");
      36         128 :         NAME_TEST;
      37             : 
      38             :         /* retrieve with SQLColAttribute */
      39         128 :         CHKColAttribute(index, SQL_DESC_NAME, name, TDS_VECTOR_SIZE(name), &len, NULL, "S");
      40         128 :         if (odbc_db_is_microsoft())
      41          96 :                 NAME_TEST;
      42         128 :         CHKColAttribute(index, SQL_DESC_LABEL, name, TDS_VECTOR_SIZE(name), &len, NULL, "S");
      43         128 :         NAME_TEST;
      44         128 : }
      45             : 
      46             : static void
      47         128 : CheckFetch(const char *c1name, const char *c1, const char *c2)
      48             : {
      49         128 :         int error = 0;
      50             : 
      51         128 :         TestName(1, c1name);
      52             : 
      53         128 :         CHKFetch("S");
      54             : 
      55         128 :         if (strlen(c1) != ind1 || strcmp(c1, col1) != 0) {
      56           0 :                 fprintf(stderr, "%s:%d: Column 1 error '%s' (%d) expected '%s' (%d)\n", __FILE__, main_line, col1, (int) ind1, c1,
      57             :                         (int) strlen(c1));
      58           0 :                 error = 1;
      59             :         }
      60             : 
      61         128 :         if (strlen(c2) != ind2 || strcmp(c2, col2) != 0) {
      62           0 :                 fprintf(stderr, "%s:%d: Column 2 error '%s' (%d) expected '%s' (%d)\n", __FILE__, main_line, col2, (int) ind2, c2,
      63             :                         (int) strlen(c2));
      64           0 :                 error = 1;
      65             :         }
      66             : 
      67         128 :         if (error)
      68           0 :                 exit(1);
      69         128 : }
      70             : 
      71             : #define CheckFetch main_line = __LINE__; CheckFetch
      72             : 
      73          10 : TEST_MAIN()
      74             : {
      75          10 :         odbc_connect();
      76             : 
      77             :         /* MSSQL 2012+, compute not supported */
      78          10 :         if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x0b000000u) {
      79           2 :                 odbc_disconnect();
      80           2 :                 return 0;
      81             :         }
      82             : 
      83           8 :         odbc_command("create table #tmp1 (c varchar(20), i int)");
      84           8 :         odbc_command("insert into #tmp1 values('pippo', 12)");
      85           8 :         odbc_command("insert into #tmp1 values('pippo', 34)");
      86           8 :         odbc_command("insert into #tmp1 values('pluto', 1)");
      87           8 :         odbc_command("insert into #tmp1 values('pluto', 2)");
      88           8 :         odbc_command("insert into #tmp1 values('pluto', 3)");
      89             : 
      90             : 
      91             :         /* 
      92             :          * TODO skip rows/column on compute (compute.c)
      93             :          * TODO check rows/column after moreresults after compute
      94             :          */
      95             : 
      96             : 
      97             :         /* select * from #tmp1 compute sum(i) */
      98           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
      99           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     100           8 :         odbc_command("select * from #tmp1 order by c, i compute sum(i)");
     101           8 :         CheckFetch("c", "pippo", "12");
     102           8 :         CheckFetch("c", "pippo", "34");
     103           8 :         CheckFetch("c", "pluto", "1");
     104           8 :         CheckFetch("c", "pluto", "2");
     105           8 :         CheckFetch("c", "pluto", "3");
     106           8 :         CHKFetch("No");
     107           8 :         CHKMoreResults("S");
     108             : 
     109             :         /* why I need to rebind ?? ms bug of feature ?? */
     110           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     111           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     112           8 :         col2[0] = '@';
     113           8 :         CheckFetch("sum", "52", "@");
     114           8 :         CHKFetch("No");
     115           8 :         CHKMoreResults("No");
     116             : 
     117             : 
     118             : 
     119             : 
     120             :         /* select * from #tmp1 order by c compute sum(i) by c */
     121           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     122           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     123           8 :         odbc_command("select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
     124           8 :         CheckFetch("mao", "pippo", "12");
     125           8 :         CheckFetch("mao", "pippo", "34");
     126           8 :         CHKFetch("No");
     127           8 :         CHKMoreResults("S");
     128             : 
     129           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     130           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     131           8 :         strcpy(col2, "##");
     132           8 :         CheckFetch("sum", "46", "##");
     133           8 :         CHKFetch("No");
     134           8 :         CHKMoreResults("S");
     135             : 
     136           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     137           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     138           8 :         CheckFetch("mao", "pluto", "1");
     139           8 :         CheckFetch("mao", "pluto", "2");
     140           8 :         CheckFetch("mao", "pluto", "3");
     141           8 :         CHKFetch("No");
     142           8 :         CHKMoreResults("S");
     143             : 
     144           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     145           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     146           8 :         strcpy(col2, "%");
     147           8 :         CheckFetch("sum", "6", "%");
     148           8 :         CHKFetch("No");
     149           8 :         CHKMoreResults("S");
     150             : 
     151           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     152           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     153           8 :         strcpy(col2, "&");
     154           8 :         CheckFetch("max", "34", "&");
     155           8 :         CHKFetch("No");
     156           8 :         CHKMoreResults("No");
     157             : 
     158             : 
     159             : 
     160             :         /* test skip recordset with computed rows */
     161             : 
     162             :         /* select * from #tmp1 where i = 2 compute min(i) */
     163           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     164           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     165           8 :         odbc_command("select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
     166           8 :         CheckFetch("c", "pippo", "34");
     167           8 :         CHKFetch("No");
     168           8 :         CHKMoreResults("S");
     169             : 
     170             :         /* here just skip results, before a row */
     171           8 :         CHKMoreResults("S");
     172             : 
     173           8 :         SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
     174           8 :         SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
     175           8 :         CheckFetch("c", "pluto", "2");
     176           8 :         CHKFetch("No");
     177           8 :         CHKMoreResults("S");
     178             : 
     179             :         /* here just skip results, before done */
     180           8 :         CHKMoreResults("No");
     181             : 
     182             : 
     183           8 :         odbc_disconnect();
     184           8 :         return 0;
     185             : }

Generated by: LCOV version 1.13