DBD-Informix

 view release on metacpan or  search on metacpan

bug-lvcnn.ec  view on Meta::CPAN

/*
** @(#)$Id: bug-lvcnn.ec,v 1.4 2007/06/14 05:13:20 jleffler Exp $
**
** Demonstration of bug originally reported in DBD::Informix
** as RT#13708 at http://rt.cpan.org/ and ignored for a couple of years.
** Primarily seems to afflict 32-bit ports of CSDK (ESQL/C).
** And primarily the more recent versions - 2.90 and maybe 2.81.
**
** Bug: SQL DESCRIPTOR does not handle LVARCHAR NOT NULL properly.
**
** Demonstrated on Solaris 10 with         CSDK 2.90.UC4.
** No bug with 64-bit on Solaris 10 with   CSDK 2.90.FC4.
** No bug with 64-bit on Linux PPC 64 with CSDK 3.00.FN125 (nightly build).
** No bug with 32-bit on Solaris 10 with   CSDK 2.80.UC1
** Core dump on 64-bit on Solaris 10 with  CSDK 2.81.FC2
** Core dump on 32-bit on Solaris 10 with  CSDK 2.81.UC2
** In each of the above cases, the test DBMS is IDS 10.00.UC5 running on Solaris 10.
** Also seen by customers on various platforms - primarily 32-bit.
*/

#include <stdlib.h>
#include <string.h>
#include <stdio.h>

$ static char lvc1[] = "This is row 1";
$ static char lvc2[] = "And this is in row 1 too";

static int num_bugs = 0;

static void print_descriptor(const char *p_name, int p_index)
{
    $ int         index = p_index;
    $ const char *name = p_name;
    $ long        coltype;
    $ long        collength;
    $ long        colind;
    $ char        colname[129];
    $ int         nullable;

    $ whenever error stop;

    $ get descriptor :name VALUE :index
            :coltype = TYPE, :collength = LENGTH,
            :nullable = NULLABLE,
            :colind = INDICATOR, :colname = NAME;
    colname[byleng(colname, strlen(colname))] = '\0';
    printf("%s:%02d: type = %2d, length = %4d, nulls = %2d, indicator = %2d, name = %s\n",
        name, index, coltype, collength, nullable, colind, colname);
}

static void check_data(void)
{
    $ lvarchar *lv1 = 0;
    $ lvarchar *lv2 = 0;
    $ int       row;
    $ short     ind;

    $ prepare p from "select row_number, lvc_with_null, lvc_wout_null from lvarchar_test order by row_number";
    $ declare c cursor for p;

    $ allocate descriptor "d" with max 3;
    $ describe p using sql descriptor "d";
    /*
    ** The following two lines do not work around the problem.
    ** $ set descriptor "d" value 2 NULLABLE = 1;
    ** $ set descriptor "d" value 3 NULLABLE = 1;
    */

    /* Print allocator description */
    print_descriptor("d", 1);
    print_descriptor("d", 2);
    print_descriptor("d", 3);

    ifx_var_flag(&lv1, 1);
    ifx_var_flag(&lv2, 1);

    $ open c;

    while (sqlca.sqlcode == 0)
    {
        $ fetch c using sql descriptor "d";
        if (sqlca.sqlcode != 0)
            break;
        $ get descriptor "d" VALUE 1 :row = DATA, :ind = INDICATOR;
        if (ind == 0)
            printf("row_number = %d:\n", row);
        else
            printf("row_number IS NULL (ind = %d)\n", ind);

        $ get descriptor "d" VALUE 2 :lv1 = DATA, :ind = INDICATOR;
        if (ind != 0)
            printf("  lvc_with_null IS NULL (ind = %d)\n", ind);
        else
        {
            char *result = (char *)ifx_var_getdata(&lv1);
            int   length = ifx_var_getlen(&lv1);
            if (length < 0)
            {
                printf("Length of lvarchar < 0\n");
                length = 0;
            }
            if (result == 0)
            {
                printf("Result of lvarchar == 0x00000000\n");
            }
            printf("  lvc_with_null = <<%.*s>>\n", length, result);
            if (strcmp(result, lvc1) != 0)
            {
                printf("**BUG** wanted  = <<%s>>\n", lvc1);
                num_bugs++;
            }
        }

        $ get descriptor "d" VALUE 3 :lv2 = DATA, :ind = INDICATOR;
        if (ind != 0)
            printf("  lvc_wout_null IS NULL (ind = %d)\n", ind);
        else
        {
            char *result = (char *)ifx_var_getdata(&lv2);



( run in 0.602 second using v1.01-cache-2.11-cpan-140bd7fdf52 )