Exemplo n.º 1
0
DB_STATUS
adu_iftrue(
ADF_CB              *adf_scb,
DB_DATA_VALUE       *dv1,
DB_DATA_VALUE       *dv2,
DB_DATA_VALUE       *rdv)
{
    i4			val;
    u_char		*nullp;


    /* Check first argument to make sure it's following the rules (first
    ** parameter must have non-nullable integer as its type)
    */
    if (dv1->db_datatype != DB_INT_TYPE)
	return(adu_error(adf_scb, E_AD2080_IFTRUE_NEEDS_INT, 0));
    
    /* result type must be nullable version of 2nd arg */
    if (-abs(dv2->db_datatype) != rdv->db_datatype)
	return(adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "adu_iftrue type"));

    /* length of result must be either the same or one greater than 2nd arg's */
    if (rdv->db_length != dv2->db_length && rdv->db_length-1 != dv2->db_length)
	return(adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "adu_iftrue len"));

    switch (dv1->db_length)
    {
      case 1:
	val = I1_CHECK_MACRO(*(i1 *)dv1->db_data);
	break;
      case 2:
	val = *(i2 *)dv1->db_data;
	break;
      case 4:
        val = *(i4 *)dv1->db_data;
	break;
      case 8:
	if (*(i8 *)dv1->db_data)
	   val = 1;
	else
	   val = 0;
	break;
      default:
	return (adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "adu_iftrue val length"));
    }

    nullp = (u_char *) rdv->db_data + rdv->db_length - 1;
    if (val)
    {
	*nullp = 0;
	MEcopy((PTR)dv2->db_data, dv2->db_length, (PTR)rdv->db_data);
    }
    else
    {
	*nullp = ADF_NVL_BIT;
    }

    return(E_DB_OK);
}
Exemplo n.º 2
0
DB_STATUS
adi_ficoerce(
ADF_CB              *adf_scb,
DB_DT_ID            adi_from_did,
DB_DT_ID            adi_into_did,
ADI_FI_ID           *adi_fid)
{
    DB_DT_ID		from_bdt = abs(adi_from_did);
    DB_DT_ID		into_bdt = abs(adi_into_did);
    DB_DT_ID		minto_bdt;
    DB_DT_ID		mfrom_bdt;
    ADI_DATATYPE	*dt;
    ADI_COERC_ENT	*cent;
    i4		        found = FALSE;

    mfrom_bdt = ADI_DT_MAP_MACRO(from_bdt);
    minto_bdt = ADI_DT_MAP_MACRO(into_bdt);

    for (;;)
    {
	/* Check the validity of the datatype ids */

        if (   (mfrom_bdt <= 0 || mfrom_bdt > ADI_MXDTS)
	    || (minto_bdt <= 0 || minto_bdt > ADI_MXDTS)
	    || Adf_globs->Adi_dtptrs[minto_bdt] == NULL
	    || (dt = Adf_globs->Adi_dtptrs[mfrom_bdt]) == NULL
	   )
	{
	    return (adu_error(adf_scb, E_AD2004_BAD_DTID, 0));
	}

	/* First check the datatypes table to see if a coercion exists */
	if (!BTtest((i4) minto_bdt, adf_scb->adf_qlang == DB_SQL
				? (char *) &dt->adi_dtcoerce_sql
				: (char *) &dt->adi_dtcoerce_quel))
	    return (adu_error(adf_scb, E_AD2009_NOCOERCION, 0));


	/* Search for the appropriate function instance id */
	for (cent = dt->adi_coerc_ents; cent->adi_from_dt == from_bdt; cent++)
	{
	    if (cent->adi_into_dt == into_bdt)
	    {
		*adi_fid = cent->adi_fid_coerc;
		found = TRUE;
		break;
	    }
	}
	break;

    }	/* end of for(;;) stmt */

    if (!found)
	return (adu_error(adf_scb, E_AD2009_NOCOERCION, 0));
    else
        return (E_DB_OK);    
}
Exemplo n.º 3
0
DB_STATUS
adi_per_under(
ADF_CB		    *adf_scb,
DB_DT_ID	    dtid,
DB_DATA_VALUE	    *under_dv)
{
    DB_STATUS       	status;
    DB_DT_ID        	mapped_id;
    ADP_POP_CB          pop_cb;

    for (;;)
    {
	mapped_id = ADI_DT_MAP_MACRO(abs(dtid));
	if (    mapped_id <= 0 || mapped_id  > ADI_MXDTS
	    || Adf_globs->Adi_dtptrs[mapped_id] == NULL
	    || !(Adf_globs->Adi_dtptrs[mapped_id]->adi_dtstat_bits
		             & AD_PERIPHERAL)
	    || Adf_globs->Adi_dtptrs[mapped_id]->adi_under_dt == 0)
	{
	    status = adu_error(adf_scb, E_AD2004_BAD_DTID, 0);
	    break;
	}

	under_dv->db_prec = 0;
	under_dv->db_length = 0;
	under_dv->db_datatype =
	    Adf_globs->Adi_dtptrs[mapped_id]->adi_under_dt;
	
	if (Adf_globs->Adi_fexi[ADI_01PERIPH_FEXI].adi_fcn_fexi == NULL)
	{
	    status = adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0);
	    break;
	}
	
	pop_cb.pop_type = (ADP_POP_TYPE);
	pop_cb.pop_length = sizeof(ADP_POP_CB);
	pop_cb.pop_ascii_id = ADP_POP_ASCII_ID;
	pop_cb.pop_underdv = under_dv;
	status = (*Adf_globs->Adi_fexi[ADI_01PERIPH_FEXI].adi_fcn_fexi)
	    (ADP_INFORMATION, &pop_cb);
	if (status)
	{
	    status = adu_error(adf_scb, E_AD7000_ADP_BAD_INFO, 0);
	    break;
	}
	
	status = adc_seglen(adf_scb, dtid, under_dv);
	break;
    }
    return(status);
}
Exemplo n.º 4
0
DB_STATUS
adu_uuid_create(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *rdv)
{
    UUID    		d;
    DB_STATUS		db_stat;
    /* Verify the result is a 16 byte binary */
    if ((rdv->db_datatype != DB_BYTE_TYPE) ||
        (rdv->db_length != sizeof(UUID)) )
    {
       db_stat = adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "uuid_create wrong type/len");
       return(db_stat);
    }
 	if (check_uuid_mac())  
		db_stat = IDuuid_create_seq(&d);
	else 
		db_stat = IDuuid_create(&d);
	/* Ignore possible return codes, e.g. RPC_S_UUID_LOCAL_ONLY */

    /* Copy the UUID into the result area */
    MEcopy(&d, rdv->db_length, rdv->db_data);

    return(E_DB_OK);
}
Exemplo n.º 5
0
DB_STATUS
adu_uuid_to_char(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *rdv)
{
    char		d[100];
    DB_STATUS		db_stat;
    UUID                u1;
    UUID                *uuid;

    /* Verify the operand is a UUID */
    if (dv1->db_datatype != DB_BYTE_TYPE)
    {
       db_stat = adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0 ,"uuid_to_char type");
       return(db_stat);
    }

    if ((ME_ALIGN_MACRO((PTR)dv1->db_data, sizeof(ALIGN_RESTRICT))
		!= (PTR)dv1->db_data) ||
		(dv1->db_length != sizeof(UUID)))
    {
	uuid = &u1;
	uuid_format(dv1, uuid);
    }
    else
	uuid = (UUID *)dv1->db_data;

    db_stat = IDuuid_to_string(uuid, d);

    if (db_stat = adu_movestring(adf_scb, (u_char *)d,(i4) STlength(d), dv1->db_datatype, rdv))
       return (db_stat);

    return(E_DB_OK);
}
Exemplo n.º 6
0
DB_STATUS
adi_tycoerce(
ADF_CB              *adf_scb,
DB_DT_ID            adi_did,
ADI_DT_BITMASK      *adi_dmsk)
{
    DB_DT_ID            bdt = abs(adi_did);
    u_i2                bm_size = sizeof(ADI_DT_BITMASK);
    i4                  n;


    for(n=1; n <= ADI_MXDTS; n++)
    {
	if (Adf_globs->Adi_datatypes[n].adi_dtid == DB_NODT) break;

	if (Adf_globs->Adi_datatypes[n].adi_dtid == bdt)
	{
	    MEcopy(adf_scb->adf_qlang == DB_SQL
			? (PTR)&Adf_globs->Adi_datatypes[n].adi_dtcoerce_sql
			: (PTR)&Adf_globs->Adi_datatypes[n].adi_dtcoerce_quel,
			bm_size, (PTR)adi_dmsk);
	    return(E_DB_OK);
	}
    }

    MEfill(bm_size, (u_char)0, (PTR)adi_dmsk);
    return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));
}
Exemplo n.º 7
0
DB_STATUS
adu_uuid_compare(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *dv2,
DB_DATA_VALUE   *rdv)
{
    i4    		d;
    DB_DATA_VALUE	exp;
    DB_STATUS		db_stat;
    UUID                u1, u2;
    UUID                *uuid1, *uuid2;

    /* Verify the result is an integer and both operands are UUIDs */
    if ((dv1->db_datatype != DB_BYTE_TYPE) ||
	(dv2->db_datatype != DB_BYTE_TYPE) ||
	(rdv->db_datatype != DB_INT_TYPE))
    {
       db_stat = adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "uuid_compare type");
       return(db_stat);
    }

    if ((ME_ALIGN_MACRO((PTR)dv1->db_data, sizeof(ALIGN_RESTRICT))
		!= (PTR)dv1->db_data) ||
		(dv1->db_length != sizeof(UUID)))
    {
	uuid1 = &u1;
	uuid_format(dv1, uuid1);
    }
    else
	uuid1 = (UUID *)dv1->db_data;

    if ((ME_ALIGN_MACRO((PTR)dv2->db_data, sizeof(ALIGN_RESTRICT))
		!= (PTR)dv2->db_data) ||
		(dv2->db_length != sizeof(UUID)))
    {
	uuid2 = &u2;
	uuid_format(dv2, uuid2);
    }
    else
	uuid2 = (UUID *)dv2->db_data;

    d = IDuuid_compare(uuid1, uuid2);

    if (rdv->db_datatype == DB_INT_TYPE && rdv->db_length == 4)
	*(i4 *)rdv->db_data = d;
    else if (rdv->db_datatype == DB_INT_TYPE && rdv->db_length == 2)
	*(i2 *)rdv->db_data = d;
    else
    {
	exp.db_datatype = DB_INT_TYPE;
	exp.db_length = 4;
	exp.db_data = (PTR) &d;
	if ((db_stat = adu_1int_coerce(adf_scb, rdv, &exp)) != E_DB_OK)
	   return (db_stat);
    }

    return(E_DB_OK);
}
Exemplo n.º 8
0
DB_STATUS
adu_uuid_from_char(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *rdv)
{
    UUID    		d;
    i4			lensrc;
    char		e[100];
    char		*srcptr;
    DB_STATUS		db_stat;

    /* Verify the result is 16 byte binary UUID */
    if ((rdv->db_datatype != DB_BYTE_TYPE) ||
        (rdv->db_length != sizeof(UUID)) ) 
    {
       db_stat = adu_error(adf_scb, E_AD9998_INTERNAL_ERROR, 2, 0, "uuid_from_char wrong type/len");
       return(db_stat);
    }

    if (db_stat = adu_lenaddr(adf_scb, dv1, &lensrc, &srcptr))
	return (db_stat);
    if(lensrc > sizeof(e)-1)
    {
       db_stat = adu_error(adf_scb, E_AD50A0_BAD_UUID_PARM, 0);
       return(db_stat);
    }
    /* Make a string */
    MEcopy(srcptr, lensrc, &e);
    e[lensrc] = 0x00;

    if((db_stat = IDuuid_from_string(&e[0], &d)) != OK)
    {
       db_stat = adu_error(adf_scb, E_AD50A0_BAD_UUID_PARM, 0);
       return(db_stat);
    }

    /* Copy the UUID into the result area */
    MEcopy(&d, rdv->db_length, rdv->db_data);

    return(E_DB_OK);
}
Exemplo n.º 9
0
DB_STATUS
adc_getempty(
ADF_CB              *adf_scb,
DB_DATA_VALUE	    *adc_emptydv)	/* Ptr to empty/null data value */
{
    i4			bdt = abs((i4) adc_emptydv->db_datatype);
    i4			bdtv;
    DB_STATUS		db_stat;


    /* Does the datatype exist? */
    bdtv = ADI_DT_MAP_MACRO(bdt);
    if (bdtv <= 0  ||  bdtv > ADI_MXDTS
	||  Adf_globs->Adi_dtptrs[bdtv] == NULL)
	return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));

    /*
    **	  If datatype is non-nullable, call the function associated with this
    ** datatype to initialize a data value to be "empty".  Currently, this is
    ** only one function for the RTI known datatypes.  This level of indirection
    ** is provided for the implementation of user-defined datatypes in the
    ** future.
    **
    **    If datatype is nullable, we can set the null value right here since it
    ** will be done the same way for all nullable datatypes.
    */

    if (adc_emptydv->db_datatype > 0)		/* non-nullable */
    {
        db_stat = (*Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(bdt)]->
				    adi_dt_com_vect.adp_getempty_addr)
	    		(adf_scb, adc_emptydv);
    }
    else
    {
	ADF_SETNULL_MACRO(adc_emptydv);
	/*
	**  If the datatype is peripheral, then we clear its length as
	**  well.  This is because ADF guarantees that the lengths are
	**  always correct for peripheral datatypes
	*/

	if (Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(bdt)]->
		    adi_dtstat_bits & AD_PERIPHERAL)
	{
	    ((ADP_PERIPHERAL *) adc_emptydv->db_data)->per_length0 = 0;
	    ((ADP_PERIPHERAL *) adc_emptydv->db_data)->per_length1 = 0;
	    ((ADP_PERIPHERAL *) adc_emptydv->db_data)->per_tag = ADP_P_COUPON;
	}
	db_stat = E_DB_OK;
    }

    return(db_stat);
}
Exemplo n.º 10
0
/*{
** Name: adu_datenow	- Retrieve current time and date
**
** Description:
**	This routine will fill the result with the INGRES internal date
**	for the current date and time.
**	
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      adu_dv				Pointer to the data value to be filled:
**		.db_datatype		Must be DB_DTE_TYPE (non-nullable DATE).
**		.db_prec		Ignored (should be zero).
**		.db_length  		Must be sizeof(DB_DATE)
**		.db_data    		Pointer to result location to fill.
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      adu_dv				Data value to be filled:
**	        .db_data    		INGRES date of "now".
**
**	Returns:
**	      The following DB_STATUS codes may be returned:
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	      If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**	    E_AD0000_OK			Completed successfully.
**	    E_AD2004_BAD_DTID		Datatype passed in was not valid
**					(must be non-nullable DATE)
**	    E_AD2005_BAD_DTLEN		Length passed in was not valid
**					(must be sizeof(DB_DATE))
**					
**      Exceptions:
**          none
**
** Side Effects:
**          none
**
** History:
**	24-oct-89 (jrb)
**	    Created.
**	19-jun-2006 (gupsh01)
**	    Added support for new datetime datatypes.
**	01-aug-2006 (gupsh01)
**	    Supply nanosecond parameter in adu_cvtime() 
**	    call.
**	29-aug-2006 (gupsh01)
**	    Removed support for ANSI datetime datatypes.
**	    date(now) is only used for ingresdate types.
**	07-nov-2006 (gupsh01)
**	    Fixed the second calculations.
**	08-Feb-2008 (kiria01) b119885
**	    Change dn_time to dn_seconds to avoid the inevitable confusion with
**	    the dn_time in AD_DATENTRNL. Also ensure that the dn structure
**	    is fully iniialised.
*/
DB_STATUS
adu_datenow(
ADF_CB		    *adf_scb,
DB_DATA_VALUE	    *adu_dv)
{
    i4			bintim_secs;
    DB_DATA_VALUE	dv_tmp;
    DB_STATUS		db_stat;
    struct timevect	tv;
    AD_NEWDTNTRNL	dn;

    /* Check validity of inputs */
    if (adu_dv->db_datatype != DB_DTE_TYPE)
	return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));

    if (adu_dv->db_length != ADF_DTE_LEN)
	return(adu_error(adf_scb, E_AD2005_BAD_DTLEN, 0));


    dv_tmp.db_datatype = DB_INT_TYPE;
    dv_tmp.db_prec = 0;
    dv_tmp.db_length = 4;
    dv_tmp.db_data = (PTR) &bintim_secs;

    if (db_stat = adu_dbconst(adf_scb, &Adf_globs->Adk_bintim_map, &dv_tmp))
	return (db_stat);

    adu_cvtime((i4) bintim_secs, 0, &tv);

    dn.dn_year	= tv.tm_year + AD_TV_NORMYR_BASE;
    dn.dn_month    = tv.tm_mon + AD_TV_NORMMON;
    dn.dn_day   = tv.tm_mday;
    dn.dn_seconds = tv.tm_hour * AD_39DTE_ISECPERHOUR +
		      tv.tm_min * AD_10DTE_ISECPERMIN +
		      tv.tm_sec;
    dn.dn_nsecond = 0;
    AD_TZ_SETNEW(&dn, 0);
    dn.dn_status = AD_DN_ABSOLUTE | AD_DN_TIMESPEC;
    dn.dn_dttype = adu_dv->db_datatype;
    return (adu_7from_dtntrnl (adf_scb, adu_dv, &dn));
}
Exemplo n.º 11
0
DB_STATUS
adi_dtinfo(
ADF_CB		    *adf_scb,
DB_DT_ID            dtid,
i4		    *dtinfo)
{
    dtid = abs(dtid);
    dtid = ADI_DT_MAP_MACRO(dtid);
    if (    dtid <= 0 || dtid  > ADI_MXDTS
	 || Adf_globs->Adi_dtptrs[dtid] == NULL
       )
	return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));

    *dtinfo = Adf_globs->Adi_dtptrs[dtid]->adi_dtstat_bits;
    return(E_DB_OK);
}
Exemplo n.º 12
0
DB_STATUS
adu_hash(
ADF_CB          *adf_scb,
DB_DATA_VALUE   *dv1,
DB_DATA_VALUE   *rdv)
{
    i4 		    in_len;
    i4 		    res_len;
    char	    *tmp;
    u_i4	    *out_p = ((u_i4 *)rdv->db_data);
    DB_STATUS	    db_stat;

    /* Don't support long data types */
    if ( Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(dv1->db_datatype)]->
		adi_dtstat_bits & AD_PERIPHERAL )
        return (adu_error(adf_scb, E_AD2090_BAD_DT_FOR_STRFUNC, 0));

    switch (dv1->db_datatype)
    {
	/* call lenaddr for the stringish types - it gets varying length
	** lengths, among other things. */
        case DB_CHA_TYPE:
        case DB_CHR_TYPE:
        case DB_BYTE_TYPE:
        case DB_VCH_TYPE:
        case DB_TXT_TYPE:
        case DB_LTXT_TYPE:
	case DB_VBYTE_TYPE:
	case DB_NCHR_TYPE:
	case DB_NVCHR_TYPE:
	 if (db_stat = adu_lenaddr(adf_scb, dv1, &in_len, &tmp))
	 return(db_stat);
	 break;
	default:	/* all the others */
	 in_len = dv1->db_length;	/* fixed length */
	 tmp = dv1->db_data;
	 break;
    }

    *out_p = -1;
    HSH_CRC32(tmp, in_len, out_p);

    return(E_DB_OK);
}
Exemplo n.º 13
0
DB_STATUS
adi_fidesc(
ADF_CB		    *adf_scb,
ADI_FI_ID	    adi_fid,
ADI_FI_DESC	    **adi_fdesc)
{
    ADI_FI_DESC		*fi;


    *adi_fdesc = (ADI_FI_DESC *) NULL;	    /* return NULL if not found */

    if (    adi_fid < (ADI_FI_ID) 0
        ||  adi_fid > Adf_globs->Adi_fi_biggest
        ||  (fi = (ADI_FI_DESC *)Adf_globs->Adi_fi_lkup[
					ADI_LK_MAP_MACRO(adi_fid)
							    ].adi_fi) == NULL
       )
	return (adu_error(adf_scb, E_AD2010_BAD_FIID, 0));

    *adi_fdesc = fi;
    return (E_DB_OK);
}
Exemplo n.º 14
0
DB_STATUS
adc_hg_dtln(
ADF_CB              *adf_scb,
DB_DATA_VALUE	    *adc_fromdv,
DB_DATA_VALUE	    *adc_hgdv)
{
    DB_STATUS		db_stat;
    i4			bdt     = abs((i4) adc_fromdv->db_datatype);
    i4			bdtv;
    i4			dtinfo;	/* Data type status bits for this type */

    for (;;)
    {
        /* Check the consistency of the input datatype id */
	bdtv = ADI_DT_MAP_MACRO(bdt);
        if (bdtv <= 0  ||  bdtv > ADI_MXDTS
		||  Adf_globs->Adi_dtptrs[bdtv] == NULL)
	{
	    db_stat = adu_error(adf_scb, E_AD2004_BAD_DTID, 0);
	    break;
	}

	/* Return error for datatypes that cannot be used in a relation or
	** do not support histograms */
	/* Get datatype status bits into dtinfo */
	db_stat = adi_dtinfo(adf_scb, adc_fromdv->db_datatype, &dtinfo);
	if (!(dtinfo & AD_INDB) || (dtinfo & AD_NOHISTOGRAM))
	{
	    /* This datatype can't be used in a relation or doesn't support
	    ** histograms */
	    db_stat = adu_error(adf_scb, E_AD3011_BAD_HG_DTID, 0);
	    break;
	}

#ifdef xDEBUG
	    /* Check the consistency of adc_fromdv's length */
	    if (db_stat = adc_lenchk(adf_scb, FALSE, adc_fromdv, NULL))
	        break;
#endif  /* xDEBUG */

	/*
	** Now call the low-level routine to do the work.  Note that if the
	** datatype is nullable, we use a temp DV_DATA_VALUE which gets set
	** to the corresponding base datatype and length.
	*/

	if (adc_fromdv->db_datatype > 0)	/* non-nullable */
	{
            db_stat = (*Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(bdt)]->
			    adi_dt_com_vect.adp_hg_dtln_addr)
				(adf_scb, adc_fromdv, adc_hgdv);
	}
	else					/* nullable */
	{
	    DB_DATA_VALUE tmp_dv = *adc_fromdv;

	    tmp_dv.db_datatype = bdt;
	    tmp_dv.db_length--;

            db_stat = (*Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(bdt)]->
			adi_dt_com_vect.adp_hg_dtln_addr)
				(adf_scb, &tmp_dv, adc_hgdv);
	}
	break;
    }	    /* end of for stmt */

    return(db_stat);
}
Exemplo n.º 15
0
DB_STATUS
adc_1hg_dtln_rti(
ADF_CB              *adf_scb,
DB_DATA_VALUE	    *adc_fromdv,
DB_DATA_VALUE	    *adc_hgdv)
{

    /* Calculate the corresponding histogram datatype and length */

    switch(adc_fromdv->db_datatype)
    {
      case DB_CHR_TYPE:
      case DB_CHA_TYPE:
      case DB_LOGKEY_TYPE:
      case DB_TABKEY_TYPE:
	adc_hgdv->db_datatype	= DB_CHA_TYPE;
	adc_hgdv->db_prec	= 0;
	if (adc_hgdv->db_length <= 0)
	 if (adc_fromdv->db_length == ADE_LEN_UNKNOWN) adc_hgdv->db_length = 8;
	 else adc_hgdv->db_length = adc_fromdv->db_length;
	else
	    adc_hgdv->db_length	= min(adc_fromdv->db_length,
				      adc_hgdv->db_length);
	if (adc_hgdv->db_length > DB_MAX_HIST_LENGTH)
	    adc_hgdv->db_length = DB_MAX_HIST_LENGTH;
	if ((adf_scb->adf_utf8_flag & AD_UTF8_ENABLED) &&
	    (adc_fromdv->db_datatype == DB_CHA_TYPE ||
	     adc_fromdv->db_datatype == DB_CHR_TYPE))
	    goto UTF8merge;
	break;

      case DB_TXT_TYPE:
      case DB_VCH_TYPE:
	adc_hgdv->db_datatype	= DB_CHA_TYPE;
	adc_hgdv->db_prec	= 0;
	if (adc_hgdv->db_length <= 0)
	 if (adc_fromdv->db_length == ADE_LEN_UNKNOWN) adc_hgdv->db_length = 8;
	 else adc_hgdv->db_length = adc_fromdv->db_length - DB_CNTSIZE;
	else
	    adc_hgdv->db_length	= min(adc_fromdv->db_length - DB_CNTSIZE,
				      adc_hgdv->db_length);
	if (adc_hgdv->db_length > DB_MAX_HIST_LENGTH)
	    adc_hgdv->db_length = DB_MAX_HIST_LENGTH;
	if (adc_hgdv->db_length == 0) /* Bug 104672 */
	    adc_hgdv->db_length = 1;
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    goto UTF8merge;
	break;

      case DB_DTE_TYPE:
      case DB_ADTE_TYPE:
	adc_hgdv->db_datatype	= DB_INT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_DTE1_HSIZE;
	break;
    
      case DB_TME_TYPE:
      case DB_TMW_TYPE:
      case DB_TMWO_TYPE:
	adc_hgdv->db_datatype	= DB_INT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_TME1_HSIZE;
	break;
    
      case DB_TSTMP_TYPE:
      case DB_TSW_TYPE:
      case DB_TSWO_TYPE:
	adc_hgdv->db_datatype	= DB_INT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_TST1_HSIZE;
	break;
    
      case DB_INYM_TYPE:
      case DB_INDS_TYPE:
	adc_hgdv->db_datatype	= DB_INT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_INT1_HSIZE;
	break;
    
      case DB_BOO_TYPE:
      case DB_FLT_TYPE:
      case DB_INT_TYPE:
	adc_hgdv->db_datatype	= adc_fromdv->db_datatype;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= adc_fromdv->db_length;
	break;

      case DB_DEC_TYPE:
	adc_hgdv->db_datatype	= DB_FLT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_DEC1_HSIZE;
	break;
	
      case DB_MNY_TYPE:
	adc_hgdv->db_datatype	= DB_INT_TYPE;
	adc_hgdv->db_prec	= 0;
	adc_hgdv->db_length	= AD_MNY1_HSIZE;
	break;

      case DB_BIT_TYPE:
	adc_hgdv->db_datatype 	= DB_BIT_TYPE;
	if (adc_fromdv->db_length > AD_BIT1_MAX_HSIZE)
	{
	    adc_hgdv->db_length = AD_BIT1_MAX_HSIZE;
	    adc_hgdv->db_prec = BITSPERBYTE;
	}
	else
	{
	    adc_hgdv->db_length	= adc_fromdv->db_length;
	    adc_hgdv->db_prec	= adc_fromdv->db_prec;
	}
	break;

      case DB_VBIT_TYPE:
      {
	DB_BIT_STRING	bs;
	i4		len;

	adc_hgdv->db_datatype 	= DB_BIT_TYPE;
	len = adc_fromdv->db_length - sizeof(bs.db_b_count);
	if (len > AD_BIT1_MAX_HSIZE)
	{
	    adc_hgdv->db_length	= AD_BIT1_MAX_HSIZE;
	    adc_hgdv->db_prec = BITSPERBYTE;
	}
	else
	{
	    adc_hgdv->db_length = len;
	    adc_hgdv->db_prec = adc_fromdv->db_prec;
	}
	break;
      }

      case DB_BYTE_TYPE:
      case DB_NBR_TYPE:
	adc_hgdv->db_datatype	= DB_BYTE_TYPE;
	adc_hgdv->db_prec	= 0;
	if (adc_hgdv->db_length <= 0)
	 if (adc_fromdv->db_length == ADE_LEN_UNKNOWN) adc_hgdv->db_length = 8;
	 else adc_hgdv->db_length = adc_fromdv->db_length;
	else
	    adc_hgdv->db_length	= min(adc_fromdv->db_length,
				      adc_hgdv->db_length);
	if (adc_hgdv->db_length > DB_MAX_HIST_LENGTH)
	    adc_hgdv->db_length = DB_MAX_HIST_LENGTH;
	break;

      case DB_VBYTE_TYPE:
	adc_hgdv->db_datatype	= DB_BYTE_TYPE;
	adc_hgdv->db_prec	= 0;
	if (adc_hgdv->db_length <= 0)
	 if (adc_fromdv->db_length == ADE_LEN_UNKNOWN) adc_hgdv->db_length = 8;
	 else adc_hgdv->db_length = adc_fromdv->db_length - DB_CNTSIZE;
	else
	    adc_hgdv->db_length	= min(adc_fromdv->db_length - DB_CNTSIZE,
				      adc_hgdv->db_length);
	if (adc_hgdv->db_length > DB_MAX_HIST_LENGTH)
	    adc_hgdv->db_length = DB_MAX_HIST_LENGTH;
	break;

      case DB_NCHR_TYPE:
      case DB_NVCHR_TYPE:
	adc_hgdv->db_prec       = 0;
	if (adc_hgdv->db_length <= 0)
	 if (adc_fromdv->db_length == ADE_LEN_UNKNOWN) adc_hgdv->db_length = 8;
	 else adc_hgdv->db_length = adc_fromdv->db_length;
	else
	    adc_hgdv->db_length	= min(adc_fromdv->db_length,
				      adc_hgdv->db_length);
UTF8merge:
	adc_hgdv->db_datatype = DB_BYTE_TYPE;
	if (adc_fromdv->db_collID != DB_UCS_BASIC_COLL)
	    /* To make room for collation weight, multiply by 4. */
	    adc_hgdv->db_length *= 4;
	if (adc_hgdv->db_length > DB_MAX_HIST_LENGTH)
	    adc_hgdv->db_length = DB_MAX_HIST_LENGTH;
	break;
	
      default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));

    }	/* end of histogram switch stmt */

    return(E_DB_OK);
}
Exemplo n.º 16
0
DB_STATUS
adc_1getempty_rti(
ADF_CB              *adf_scb,
DB_DATA_VALUE       *adc_emptydv)	/* Ptr to empty data value */
{

#ifdef	xDEBUG
    DB_STATUS   db_stat;

    /* check the validity of the length of the data value */
    if (db_stat = adc_lenchk(adf_scb, FALSE, adc_emptydv, NULL))
	return(db_stat);
#endif	/* xDEBUG */

    /* fill up the data value with the "default-default" value. */
    switch (adc_emptydv->db_datatype)
    {
      case DB_CHA_TYPE:
      case DB_CHR_TYPE:
	/* fill character data with blanks. */
	MEfill(adc_emptydv->db_length, (u_char)' ', adc_emptydv->db_data);
	break;

      case  DB_NCHR_TYPE:
            *(UCS2 *) adc_emptydv->db_data = U_BLANK;
	break;

      case DB_LOGKEY_TYPE:
      case DB_TABKEY_TYPE:
	/* fill character data with zeros. */
	MEfill(adc_emptydv->db_length, (u_char)0, adc_emptydv->db_data);
	break;

      case DB_DTE_TYPE:
	{
	    AD_DATENTRNL    *dp = (AD_DATENTRNL *) adc_emptydv->db_data;

	    /* Date datatypes are defaultable by set status to AD_DN_NULL. */
	    dp->dn_status   = AD_DN_NULL;
	    dp->dn_year	    = 0;
	    dp->dn_month    = 0;
	    dp->dn_highday  = 0;
	    dp->dn_lowday   = 0;
	    dp->dn_time	    = 0;
	}
	break;

      case DB_ADTE_TYPE:
        {
	     AD_ADATE *ad = (AD_ADATE *) adc_emptydv->db_data;

	     ad->dn_year = 0;
	     ad->dn_month = 0;
	     ad->dn_day = 0;
        }
        break;

       case DB_TMWO_TYPE:
       case DB_TMW_TYPE:
       case DB_TME_TYPE:
        {
	     AD_TIME *adtm = (AD_TIME *) adc_emptydv->db_data;

	     adtm->dn_seconds = 0;
	     adtm->dn_nsecond = 0;
	     AD_TZ_SET(adtm, 0);
        }
        break;

       case DB_TSWO_TYPE:
       case DB_TSW_TYPE:
       case DB_TSTMP_TYPE:
        {
	     AD_TIMESTAMP *atstmp = (AD_TIMESTAMP *) adc_emptydv->db_data;

	     atstmp->dn_year = 0;
	     atstmp->dn_month = 0;
	     atstmp->dn_day = 0;
	     atstmp->dn_seconds = 0;
	     atstmp->dn_nsecond = 0;
	     AD_TZ_SET(atstmp, 0);
        }
        break;

       case DB_INYM_TYPE:
        {
	     AD_INTYM *aintym = (AD_INTYM *) adc_emptydv->db_data;

	     aintym->dn_years = 0;
	     aintym->dn_months = 0;
        }
        break;

       case DB_INDS_TYPE:
        {
	     AD_INTDS *aintds = (AD_INTDS *) adc_emptydv->db_data;

	     aintds->dn_days = 0;
	     aintds->dn_seconds = 0;
	     aintds->dn_nseconds = 0;
        }
        break;

      case DB_BOO_TYPE:
        ((DB_ANYTYPE *)adc_emptydv->db_data)->db_booltype = DB_FALSE;
        break;

      case DB_INT_TYPE:
	if (adc_emptydv->db_length == 1)
	    *(i1 *) adc_emptydv->db_data = 0;
	else if (adc_emptydv->db_length == 2)
	    *(i2 *) adc_emptydv->db_data = 0;
	else if (adc_emptydv->db_length == 4)
	    *(i4 *) adc_emptydv->db_data = 0;
	else if (adc_emptydv->db_length == 8)
	    *(i8 *) adc_emptydv->db_data = 0;
	break;

      case DB_DEC_TYPE:
	MEfill(adc_emptydv->db_length, (u_char)0, adc_emptydv->db_data);
	((u_char *)adc_emptydv->db_data)[adc_emptydv->db_length-1] = MH_PK_PLUS;
	break;

      case DB_FLT_TYPE:
	if (adc_emptydv->db_length == 4)
	    *(f4 *) adc_emptydv->db_data = 0.0;
	else
	    *(f8 *) adc_emptydv->db_data = 0.0;
	break;

      case DB_MNY_TYPE:
	((AD_MONEYNTRNL *) adc_emptydv->db_data)->mny_cents= 0.0;
	break;

      case DB_VCH_TYPE:
      case DB_TXT_TYPE:
      case DB_LTXT_TYPE:
      case DB_VBYTE_TYPE:
	((DB_TEXT_STRING *) adc_emptydv->db_data)->db_t_count = 0;
	*((DB_TEXT_STRING *)adc_emptydv->db_data)->db_t_text = '\0';
	break;

      case DB_LVCH_TYPE:
      case DB_LBYTE_TYPE:
      case DB_GEOM_TYPE:
      case DB_POINT_TYPE:
      case DB_MPOINT_TYPE:
      case DB_LINE_TYPE:
      case DB_MLINE_TYPE:
      case DB_POLY_TYPE:
      case DB_MPOLY_TYPE:
      case DB_GEOMC_TYPE:
      case DB_LBIT_TYPE:
      case DB_LNVCHR_TYPE:
	{
	    ADP_PERIPHERAL	*periph = (ADP_PERIPHERAL *)
						adc_emptydv->db_data;
	    periph->per_tag = ADP_P_DATA;
	    periph->per_length0 = periph->per_length1 = 0;
	}
	break;

      case DB_LBLOC_TYPE:
      case DB_LCLOC_TYPE:
      case DB_LNLOC_TYPE:
	{
	    ADP_PERIPHERAL	*periph = (ADP_PERIPHERAL *)
						adc_emptydv->db_data;
	    periph->per_tag = ADP_P_LOC_L_UNK;
	    periph->per_length0 = periph->per_length1 = 0;
	    MEfill (sizeof(ADP_LOCATOR), 0, ((char *)periph + ADP_HDR_SIZE)); 
	}
	break;
	

      case DB_VBIT_TYPE:
	((DB_BIT_STRING *) adc_emptydv->db_data)->db_b_count = 0;
	break;

      case DB_BIT_TYPE:
      case DB_BYTE_TYPE:
      case DB_NBR_TYPE:
	MEfill(adc_emptydv->db_length, (u_char)0, adc_emptydv->db_data);
	break;

      case DB_NVCHR_TYPE:
	((DB_NVCHR_STRING *) adc_emptydv->db_data)->count = 0;
	break;

      default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }
    return(E_DB_OK);
}
Exemplo n.º 17
0
DB_STATUS
adi_cpficoerce(
ADF_CB              *adf_scb,
DB_DT_ID            adi_from_did,
DB_DT_ID            adi_into_did,
ADI_FI_ID           *adi_fid)
{
    DB_DT_ID		from_bdt = abs(adi_from_did);
    DB_DT_ID		into_bdt = abs(adi_into_did);
    ADI_FI_DESC	        *fi_desc_ptr;
    i4		        found = FALSE;
    DB_STATUS		db_stat;
    DB_DT_ID		minto_bdt;
    DB_DT_ID		mfrom_bdt;
    
    mfrom_bdt = ADI_DT_MAP_MACRO(from_bdt);
    minto_bdt = ADI_DT_MAP_MACRO(into_bdt);

    for (;;)
    {
	/* Check the validity of the datatype ids */

        if (   (mfrom_bdt <= 0 || mfrom_bdt > ADI_MXDTS)
	    || (minto_bdt <= 0 || minto_bdt > ADI_MXDTS)
	    || Adf_globs->Adi_dtptrs[mfrom_bdt] == NULL
	    || Adf_globs->Adi_dtptrs[minto_bdt] == NULL
	   )
	{
	    return (adu_error(adf_scb, E_AD2004_BAD_DTID, 0));
	}

	/* Search for the appropriate COPY COERCION function instance id */
	for (fi_desc_ptr = (ADI_FI_DESC *)&Adf_globs->Adi_fis[Adf_globs->
						   Adi_copy_coercion_fis];
		(   fi_desc_ptr->adi_fitype == ADI_COPY_COERCION
		 && fi_desc_ptr->adi_finstid != ADFI_ENDTAB
		);
	     fi_desc_ptr++
	    )
	{
	    if (fi_desc_ptr->adi_finstid == ADI_NOFI)
		continue;   /* Hole in fitab ... skip this one. */

	    if (fi_desc_ptr->adi_dtresult == into_bdt
		&& fi_desc_ptr->adi_dt[0] == from_bdt
	       )
	    {
		*adi_fid = fi_desc_ptr->adi_finstid;
		found = TRUE;
		return (E_DB_OK);
	    }
	}
	break;

    }	/* end of for(;;) stmt */


    /* Attempt to find normal COERCION function instance ID */

    if (db_stat = adi_ficoerce(adf_scb, from_bdt, into_bdt, adi_fid))
    {
	if (adf_scb->adf_errcb.ad_errcode == E_AD2009_NOCOERCION)
	    db_stat = adu_error(adf_scb, E_AD200A_NOCOPYCOERCION, 0);
    }
    return (db_stat);
}
Exemplo n.º 18
0
/*{
** Name: adu_rdm2_finish	- Finish Redeeming an ADF_COUPON
**
** Description:
**      This routine completes the action of redeeming a coupon.
**      If running in test mode, this routine makes sure that the
**      varchar field is padded out with the appropriate amount of
**      garbage.
**
**      In general, it places the "closing remarks" in the
**      data stream.  This means that it will place the final segment
**      indicator (saying "no more") in the stream if the stream is
**      destined for GCA.  If the datatype is nullable, then the null
**      bit is set/cleared as appropriate.  If there is insufficient
**      room to make these closing remarks (or to supply the correct
**      amount of garbage in the test case), then the fip_state is set
**      to ADW_F_DONE_NEED_NULL, and an incomplete status is returned.
**      This status will set up the main redeem call to call this
**      routine again with a new buffer, repeating this action until
**      all is done.
**
** Inputs:
**      adf_scb                        Standard ADF SCB Ptr
**      result_dv                      Ptr to output area DB_DATA_VALUE
**      coupon_dv                      PTR to input area DB_DATA_VALUE
**      work                           Ptr to ADP_LO_WKSP in which work
**                                         is done.
**          ->adw_shared               Contains the result of the action
**                                         so far
**          ->adw_fip                  Contains more such results
**      for_gca                        Nat indicating whether the result
**                                         is destined for GCA
**                                         transmission.
**
** Outputs:
**      adf_scb->adf_error             Filled as appropriate.
**      result_dv->db_length           Set correctly.
**      work->adw_fip.fip_state        Set to indicate whether to
**                                         return.
**      work->adw_fip.fip_test*        Set to control the garbage
**                                         returned for the test cases.
**
**	Returns:
**	    DB_STATUS
**	Exceptions:
**	    None
**
** Side Effects:
**	    None
**
** History:
**      07-dec-1989 (fred)
**          Prototyped.
**      06-oct-1992 (fred)
**          Altered to work with timezone integration.  As a temporary measure,
**	    this routine was using the ADF_CB.adf_4rsvd field to store
**	    some context across calls.  In that this field disappeared, a new,
**	    more appropriately named field was added (adf_lo_context).  This
**	    new ADF_CB field is now used in this file.
**	30-Oct-1992 (fred)
**	    Fixed to correctly handle being called with a length too short
**	    for the original header.
**	20-Nov-1992 (fred)
**	    Rewritten for better clarity & better delineation of
**	    function in support of OME large objects.
[@history_template@]...
*/
DB_STATUS static
adu_rdm2_finish(ADF_CB             *adf_scb,
		DB_DATA_VALUE      *result_dv,
		DB_DATA_VALUE      *coupon_dv,
		ADP_LO_WKSP        *work,
		i4                for_gca)
{
    DB_STATUS         status = E_DB_OK;
    i4                zero = 0;

    if (work->adw_shared.shd_l1_check != work->adw_fip.fip_l1_value)
    {
	/* Fix_me -- get more detailed error message to log (log_key, */
	/* what's wrong, etc. */

	/* Then we are sending an inconsistent blob */

	status = adu_error(adf_scb, E_AD7004_ADP_BAD_BLOB,0);
    }
    else if (result_dv->db_length >=
	     (work->adw_shared.shd_o_used + (for_gca * sizeof(i4)) +
	                                        work->adw_fip.fip_null_bytes))

    {
	if (for_gca)
	{
	    I4ASSIGN_MACRO(zero,
			   result_dv->db_data[work->adw_shared.shd_o_used]);
	    work->adw_shared.shd_o_used += sizeof(i4);
	}
	if (work->adw_fip.fip_test_mode)
	{
	    work->adw_fip.fip_test_sent += sizeof(i4);
	    if (work->adw_fip.fip_test_sent <=
		    (work->adw_fip.fip_test_length -
		                      work->adw_fip.fip_null_bytes))

	    {
		/* Then there isn't enough to fill the varchar() */

		if (result_dv->db_length <
		    (work->adw_fip.fip_test_length
		         - work->adw_fip.fip_test_sent))
		{
		    /*
		    ** This is for test purposes only.
		    **
		    ** We need to send a true VARCHAR() datatype.
		    ** Thus, if the blob os smaller than that, then we
		    ** need to pad it out with garbage bytes.  To do
		    ** so, we will increment test_sent by the
		    ** remainder of the buffer, and happily return,
		    ** knowing that we will arrive here with an empty
		    ** buffer in the relatively near future.
		    **
		    ** To set test_sent appropriately, we must first
		    ** decrement it by the amount it was incremented
		    ** before arriving here.  Then we increment as
		    ** appropriate.
		    */
		
		    work->adw_fip.fip_test_sent -=
			work->adw_shared.shd_o_used; 
		    work->adw_fip.fip_test_sent += result_dv->db_length;
		    work->adw_fip.fip_state = ADW_F_DONE_NEED_NULL;
		    adf_scb->adf_errcb.ad_errcode  = E_AD0002_INCOMPLETE;
		    status = E_DB_INFO;
		}
	    }
	}
	
	if (status == E_DB_OK)
	{
	    result_dv->db_length = work->adw_shared.shd_o_used +
		    work->adw_fip.fip_null_bytes;
	    
	    if (work->adw_fip.fip_null_bytes)
	    {
		/*
		**	Then the datatype was nullable.  Copy the NULL byte
		**	from the coupon.
		*/
		
		if (ADI_ISNULL_MACRO(coupon_dv))
		{
		    ADF_SETNULL_MACRO(result_dv);
		}
		else
		{
		    ADF_CLRNULL_MACRO(result_dv);
		}
	    }
	    adf_scb->adf_errcb.ad_errcode = E_DB_OK;
	}
    }
    else
    {
	/*
	**  In this case, we are at the end of data, but the "closing
	**	remarks" (no more strings (if gca) and null bytes) doesn't
	**	fit in the buffer.
	**
	**  We mark this fact by setting the state to ADW_F_DONE_NEED_NULL.
	*/
	result_dv->db_length = work->adw_shared.shd_o_used;
	work->adw_fip.fip_state = ADW_F_DONE_NEED_NULL;

	adf_scb->adf_errcb.ad_errcode  = E_AD0002_INCOMPLETE;
	status = E_DB_INFO;
    }

    return(status);
}
Exemplo n.º 19
0
DB_STATUS
adi_tyid(
ADF_CB             *adf_scb,
ADI_DT_NAME        *adi_dname,
DB_DT_ID           *adi_did)
{
    i4                  s;
    i4                  n;
    i4                  i;
    i4                  cmp;
    char		*c1;
    char		*c2;
    ADI_DT_NAME         dt_name;
    bool		dategiven = FALSE;

    s = sizeof(adi_dname->adi_dtname);
    c2 = &adi_dname->adi_dtname[0];

    if (c2 && ((*c2 == 'd') || (*c2 == 'D')))
    {
          if (STbcompare (c2, 0, "date", 0, TRUE) == 0)
          {
	    dategiven = TRUE;
            if (adf_scb->adf_date_type_alias & AD_DATE_TYPE_ALIAS_INGRES)
            {
                /* replace the input string with ingresdate */
                MEmove(10, (PTR)"ingresdate", '\0',
                                sizeof(ADI_DT_NAME), (PTR)&dt_name.adi_dtname);
		dt_name.adi_dtname[10]='\0';
            }
            else if (adf_scb->adf_date_type_alias & AD_DATE_TYPE_ALIAS_ANSI)
            {
                /* replace the input string with ansidate */
                MEmove(8, (PTR)"ansidate", '\0',
                                sizeof(ADI_DT_NAME), (PTR)&dt_name.adi_dtname);
		dt_name.adi_dtname[8]='\0';
            }
            else
            {
                return (adu_error(adf_scb, E_AD5065_DATE_ALIAS_NOTSET, 0));
            }
          }
    }

    for(n=1; n <= ADI_MXDTS; n++)
    {
	if (Adf_globs->Adi_datatypes[n].adi_dtid == DB_NODT) break;

	cmp = 1;
	c1 = &Adf_globs->Adi_datatypes[n].adi_dtname.adi_dtname[0];
	if (dategiven == TRUE)
	  c2 = (PTR)&dt_name.adi_dtname;
	else
    	  c2 = &adi_dname->adi_dtname[0];
	i = 0;

	while ((i++ < s)  &&  (*c1 != 0  ||  *c2 != 0))
	{
	    if (*c1++ != *c2++)
	    {
		cmp = 0;
		break;
	    }
	}

	if (cmp)
	{
	    *adi_did = Adf_globs->Adi_datatypes[n].adi_dtid;
	    return(E_DB_OK);
	}
    }

    *adi_did = DB_NODT;
    return(adu_error(adf_scb, E_AD2003_BAD_DTNAME, 0));
}
Exemplo n.º 20
0
static	DB_STATUS
ad0_llklmatch(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    *rcmp)
{
    ADULcstate		savep;
    i4			cc;
    i4			cur_state = AD_S1_IN_RANGE_DASH_NORM;
    bool		empty_range = TRUE;
    bool		match_found = FALSE;

    adulnext(pst);
    for (;;)
    {
	/*
	** Get the next character from the pattern string,
	** handling escape sequences, and ignoring blanks if required.
	** -----------------------------------------------------------
	*/
	if (adulptr(pst) >= endp)
	{
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));
	}
	else
	{
	    if (est != NULL  && !adulcmp(pst, est))
	    {
		/* we have an escape sequence */
		adulnext(pst);
		if (adulptr(pst) >= endp)
		{
		    /* ERROR:  escape at end of pattern string not allowed */
		    return (adu_error(adf_scb, E_AD1017_ESC_AT_ENDSTR, 0));
		}
		switch (adultrans(pst)/COL_MULTI)
		{
		  case AD_1LIKE_ONE:
		  case AD_2LIKE_ANY:
		  case '-':
		    cc = AD_CC0_NORMAL;
		    break;

		  case AD_3LIKE_LBRAC:
		    cc = AD_CC4_LBRAC;
		    break;

		  case AD_4LIKE_RBRAC:
		    cc = AD_CC5_RBRAC;
		    break;

		  default:
		    if (!adulcmp(pst, est))
			cc = AD_CC0_NORMAL;
		    else
			/* ERROR:  illegal escape sequence */
			return (adu_error(adf_scb, E_AD1018_BAD_ESC_SEQ, 0));
		    break;
		}
	    }
	    else
	    {
		/* not an escape character */
		switch (adultrans(pst)/COL_MULTI)
		{
		  case AD_1LIKE_ONE:
		    cc = AD_CC2_ONE;
		    break;

		  case AD_2LIKE_ANY:
		    cc = AD_CC3_ANY;
		    break;

		  case '-':
		    cc = AD_CC1_DASH;
		    break;

		  case AD_3LIKE_LBRAC:
		  case AD_4LIKE_RBRAC:
		  default:
		    cc = AD_CC0_NORMAL;
		    break;
		}
	    }
	}

	if (cc == AD_CC6_EOS)
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	if (cc == AD_CC2_ONE  ||  cc == AD_CC3_ANY  ||  cc == AD_CC4_LBRAC)
	    return (adu_error(adf_scb, E_AD1016_PMCHARS_IN_RANGE, 0));

	if (	bignore
	    &&	cc == AD_CC0_NORMAL
	    &&	(adulspace(pst)  || adulisnull(pst))
	   )
	{
	    adulnext(pst);
	    continue;	/* ignore blanks and null chars for the C datatype */
	}


	/*
	** Now, we have the next pattern character.  Switch on the current
	** state, then do something depending on what character class
	** the next pattern character falls in.  Note, that we should be
	** guaranteed at this point to have either `NORMAL', `DASH', or `RBRAC'.
	** All other cases have been handled above as error conditions.
	*/

	switch (cur_state)
	{
	  case AD_S1_IN_RANGE_DASH_NORM:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
	      case AD_CC1_DASH:
		empty_range = FALSE;
		STRUCT_ASSIGN_MACRO(*pst, savep);
		cur_state = AD_S2_IN_RANGE_DASH_IS_OK;
	        break;

	      case AD_CC5_RBRAC:
		/* end of the range spec, range *MUST* have been empty. */
		adulnext(pst);
		return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S2_IN_RANGE_DASH_IS_OK:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		if (adulptr(sst) < ends && adulcmp(sst, &savep) == 0)
		    match_found = TRUE;
		STRUCT_ASSIGN_MACRO(*pst, savep);
		/* cur_state remains AD_S2_IN_RANGE_DASH_IS_OK */
	        break;

	      case AD_CC1_DASH:
		/* do nothing, but change cur_state */
		cur_state = AD_S3_IN_RANGE_AFTER_DASH;
	        break;

	      case AD_CC5_RBRAC:
		/* end of the range spec, and we have a saved char so range */
		/* was not empty.					    */
		if (adulptr(sst) < ends && adulcmp(sst, &savep) == 0)
		    match_found = TRUE;

		if (match_found)
		{
		    adulnext(sst);
		    adulnext(pst);
		    return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));
		}
		*rcmp = -1;	/* if string not in range, call it < pat */
		return (E_DB_OK);

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S3_IN_RANGE_AFTER_DASH:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		if (adulcmp(&savep, pst) <= 0)
		{
		    if (    adulptr(sst) < ends
			&&  adulcmp(sst, &savep) >= 0
		        &&  adulcmp(sst, pst) <= 0
		       )
		    {
			match_found = TRUE;
		    }
		    cur_state = AD_S4_IN_RANGE_DASH_NOT_OK;
		    break;
		}
		/* fall through to BAD-RANGE ... x-y, where x > y */

	      case AD_CC1_DASH:
	      case AD_CC5_RBRAC:
		return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  case AD_S4_IN_RANGE_DASH_NOT_OK:
	    switch (cc)
	    {
	      case AD_CC0_NORMAL:
		STRUCT_ASSIGN_MACRO(*pst, savep);
		cur_state = AD_S2_IN_RANGE_DASH_IS_OK;
	        break;

	      case AD_CC1_DASH:
		return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	      case AD_CC5_RBRAC:
		/* end of the range spec, no saved char, and range was not  */
		/* empty.						    */
		if (match_found)
		{
		    adulnext(sst);
		    adulnext(pst);
		    return (ad0_llike(adf_scb, sst, ends, pst, endp,
					    est, bignore, rcmp));
		}
		*rcmp = -1;	/* if string not in range, call it < pat */
		return (E_DB_OK);

	      default:
		/* should *NEVER* get here */
		return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	    break;

	  default:
	    /* should *NEVER* get here */
	    return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	}
	adulnext(pst);
    }
}
Exemplo n.º 21
0
DB_STATUS
adu_copascii(
ADF_CB		*adf_scb,
DB_DATA_VALUE	*dv1,
DB_DATA_VALUE	*rdv)
{
    register char       *p;
    char		temp[ADI_OUTMXFIELD];
    i4			leftfill;
    i4			plen;
    i4			str_len;
    i2			out_width;

    p = temp;

    switch(dv1->db_datatype)
    {
      case DB_INT_TYPE:
        if (dv1->db_length == 8)
        {
            CVla8(*(i8 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 4)
        {
            CVla(*(i4 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 2)
        {
            CVla((i4) *(i2 *) dv1->db_data, p);
        }
        else
        {
            CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p);
        }

        break;

      case DB_DEC_TYPE:
	{
	    i4		pr = DB_P_DECODE_MACRO(dv1->db_prec);
	    i4		sc = DB_S_DECODE_MACRO(dv1->db_prec);
	    i4		available_width = rdv->db_length;
	    char	decimal = (adf_scb->adf_decimal.db_decspec
					? (char) adf_scb->adf_decimal.db_decimal
					: '.'
				  );
				  
	    if (    rdv->db_datatype == DB_VCH_TYPE
		||  rdv->db_datatype == DB_TXT_TYPE
		||  rdv->db_datatype == DB_LTXT_TYPE
	       )
		available_width -= DB_CNTSIZE;

	    /* now convert to ascii: use formula from lenspec for length, get
	    ** scale # of digits after decimal point, use left-justify
	    */
	    if (CVpka((PTR)dv1->db_data, pr, sc, decimal,
		    AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len)
		== CV_OVERFLOW)
	    {
		/* this should never happen */
		return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }

	    if (str_len > available_width)
		return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	}
        break;

      case DB_FLT_TYPE:
	{
	    char    decimal = (adf_scb->adf_decimal.db_decspec ?
				(char) adf_scb->adf_decimal.db_decimal : '.');
	    i4	    available_width = rdv->db_length;


	    if (    rdv->db_datatype == DB_VCH_TYPE
		||  rdv->db_datatype == DB_TXT_TYPE
		||  rdv->db_datatype == DB_LTXT_TYPE
	       )
		available_width -= DB_CNTSIZE;

	    if (dv1->db_length == 4)
	    {
		f8 f8tmp = (f8) *(f4 *) dv1->db_data;

                /*  BUG : b119968
		**
		**  CVfa is a utility routine for both f8 and f4 floats.
		**  In the f4 case, the value is converted to f8 prior 
		**  to call (as here).
		**
		**  This works well except for the boundary case, where 
		**  the f4 is FLT_MAX. In this case, an effective 
		**  rounding up of the f8 that occurs as we convert to 
		**  a string (eventually through fcvt) "overflows" the 
		**  original f4 value.
		**
		**  We bump down the last sig bit of the f4, and then
		**  we have no problems.
		*/
		if ( f8tmp == FLT_MAX )
		{
		    f8tmp = FLT_MAX_ROUND;
		} 
                else if ( f8tmp == -FLT_MAX ) 
		{
		    f8tmp = -FLT_MAX_ROUND;
		} 
		CVfa(f8tmp,
		     adf_scb->adf_outarg.ad_f4width,
		     adf_scb->adf_outarg.ad_f4prec,
		     adf_scb->adf_outarg.ad_f4style,
		     decimal, p, &out_width);

		if (out_width > available_width)
		    return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	    }
	    else
	    {
		CVfa(*(f8 *)dv1->db_data,
		     adf_scb->adf_outarg.ad_f8width,
		     adf_scb->adf_outarg.ad_f8prec,
		     adf_scb->adf_outarg.ad_f8style,
		     decimal, p, &out_width);

		if (out_width > available_width)
		    return(adu_error(adf_scb, E_AD1030_F_COPY_STR_TOOSHORT, 0));
	    }
	}
	break;

      default:
	return(adu_error(adf_scb, E_AD5002_BAD_NUMBER_TYPE, 0));
    }

    while (*p == ' ')
        p++;

    /*
    ** TEXT, VARCHAR, and LONGTEXT are variable length copies,
    ** so no need to pad on the left.
    */
    if (    rdv->db_datatype == DB_TXT_TYPE
	||  rdv->db_datatype == DB_VCH_TYPE
	||  rdv->db_datatype == DB_LTXT_TYPE
       )	
    {
        return(adu_movestring(adf_scb, (u_char *) p, 
				(i4) STlength(p), dv1->db_datatype, rdv));
    }

    /*
    ** At this point the result type can be C or CHAR
    */
    plen     = min(STlength(p), rdv->db_length);
    leftfill = rdv->db_length - plen;

    MEfill(leftfill, ' ', rdv->db_data);
    MEcopy((PTR)p, plen, (PTR)((char *)rdv->db_data + leftfill));

    return(E_DB_OK);
}
Exemplo n.º 22
0
DB_STATUS
adu_ascii(
ADF_CB			*adf_scb,
register DB_DATA_VALUE	*dv1,
DB_DATA_VALUE		*rdv)
{
    DB_STATUS           db_stat = E_DB_OK;
    register char       *p;
    char		temp[ADI_OUTMXFIELD]; /* could probably be smaller */
    u_char		*str_addr;
    i4			str_len;
    i2			reswidth;
    bool		char_text = FALSE;
    i8			i8_tmp = 0;

    p = temp;

    switch(dv1->db_datatype)
    {
      case DB_INT_TYPE:
        if (dv1->db_length == 8)
	{
            CVla8(*(i8 *) dv1->db_data, p);
	}
        else if (dv1->db_length == 4)
        {
            CVla(*(i4 *) dv1->db_data, p);
        }
        else if (dv1->db_length == 2)
        {
            CVla((i4) (*(i2 *) dv1->db_data), p);
        }
        else
        {
            CVla(I1_CHECK_MACRO(*(i1 *) dv1->db_data), p);
        }

        break;

      case DB_BOO_TYPE:
        if (((DB_ANYTYPE *)dv1->db_data)->db_booltype == DB_FALSE)
            STcopy("FALSE", p);
        else
            STcopy("TRUE", p);
        break;

      case DB_VCH_TYPE:
      case DB_CHA_TYPE:
      case DB_CHR_TYPE:
      case DB_TXT_TYPE:
      case DB_LTXT_TYPE:
      case DB_BYTE_TYPE:
      case DB_VBYTE_TYPE:
	if ((db_stat = adu_3straddr(adf_scb, dv1, (char **) &str_addr)))
	    return(db_stat);
	if ((db_stat = adu_size(adf_scb, dv1, &str_len)))
	    return(db_stat);
        if ((db_stat = adu_movestring(adf_scb, str_addr, str_len, 
					dv1->db_datatype, rdv)))
	    return(db_stat);
        char_text = TRUE;

        break;

      case DB_DEC_TYPE:
	{
	    i4		pr = DB_P_DECODE_MACRO(dv1->db_prec);
	    i4		sc = DB_S_DECODE_MACRO(dv1->db_prec);
	    char	decimal = (adf_scb->adf_decimal.db_decspec
					? (char) adf_scb->adf_decimal.db_decimal
					: '.'
				  );
				  
	    /* now convert to ascii: use formula from lenspec for length, get
	    ** scale # of digits after decimal point, use left-justify option
	    */
	    if (CVpka((PTR)dv1->db_data, pr, sc, decimal,
		    AD_PS_TO_PRN_MACRO(pr, sc), sc, CV_PKLEFTJUST, p, &str_len)
		== CV_OVERFLOW)
	    {
		/* this should never happen */
		return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	}
        break;

      case DB_FLT_TYPE:
	{
	    char    decimal = (adf_scb->adf_decimal.db_decspec ?
				(char) adf_scb->adf_decimal.db_decimal : '.');
	    
	    if (dv1->db_length == 4)
	    {
		CVfa((f8) *(f4 *) dv1->db_data,
		     adf_scb->adf_outarg.ad_f4width,
		     adf_scb->adf_outarg.ad_f4prec,
		     adf_scb->adf_outarg.ad_f4style,
		     decimal, p, &reswidth);
	    }
	    else
	    {
		CVfa(*(f8 *)dv1->db_data,
		     adf_scb->adf_outarg.ad_f8width,
		     adf_scb->adf_outarg.ad_f8prec,
		     adf_scb->adf_outarg.ad_f8style,
		     decimal, p, &reswidth);
	    }
	}
        break;

      case DB_DTE_TYPE:
      case DB_ADTE_TYPE:
      case DB_TMWO_TYPE:
      case DB_TMW_TYPE:
      case DB_TME_TYPE:
      case DB_TSWO_TYPE:
      case DB_TSW_TYPE:
      case DB_TSTMP_TYPE:
      case DB_INYM_TYPE:
      case DB_INDS_TYPE:
	return( adu_6datetostr( adf_scb, dv1, rdv));
	       
      case DB_MNY_TYPE:
	return( adu_9mnytostr( adf_scb, dv1, rdv));

      case DB_LVCH_TYPE:
      case DB_LBYTE_TYPE:
      case DB_GEOM_TYPE:
      case DB_POINT_TYPE:
      case DB_MPOINT_TYPE:
      case DB_LINE_TYPE:
      case DB_MLINE_TYPE:
      case DB_POLY_TYPE:
      case DB_MPOLY_TYPE:
      case DB_GEOMC_TYPE:
      case DB_LNVCHR_TYPE:
      case DB_LCLOC_TYPE:
      case DB_LBLOC_TYPE:
      case DB_LNLOC_TYPE:
	return( adu_lvch_move( adf_scb, dv1, rdv));
	
      case DB_BIT_TYPE:
      case DB_VBIT_TYPE:
	return( adu_bit2str( adf_scb, dv1, rdv));
	
      case DB_LOGKEY_TYPE:
      case DB_TABKEY_TYPE:
	return( adu_3logkeytostr( adf_scb, dv1, rdv));

      default:
	return(adu_error(adf_scb, E_AD2090_BAD_DT_FOR_STRFUNC, 0));
    }

    if (!char_text)
    {
        if ((db_stat = adu_movestring(adf_scb, (u_char *) p,
				      (i4) STlength(p), 
				      dv1->db_datatype, rdv))
	    != E_DB_OK
	   )
	    return(db_stat);
    }

    return(E_DB_OK);
}
Exemplo n.º 23
0
/*{
** Name: adc_dbtoev	- Determine which type to export
**
** Description:
**      This routine, given an input datatype, determines which type to send to
**	output.  It is assumed that a coercion exists for this datatype
**	transformation.
**
**	If the datatype is exportable (AD_NOEXPORT is not set), then the result
**	datatype is identical with the input.  Otherwise, a call is made to the
**	dbtoev routine specified in the datatype com vector. 
**
**	If the input is nullable, then the output is nullable as well. 
**
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      db_value			Ptr to db_data_value for database
**					type/prec/length
**      ev_value                        Pointer to DB_DATA_VALUE for exported type
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      *ev_value                       Filled appropriately.
**
**	Returns:
**	      The following DB_STATUS codes may be returned:
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	      If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**          E_AD0000_OK                 Operation succeeded.
**          E_AD2004_BAD_DTID           Datatype id unknown to ADF.
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**      07-apr-89 (fred)
**          Created.
**	11-jul-89 (jrb)
**	    Removed unused variables.
**      29-oct-1992 (stevet)
**          Added check for protocol level support to see if decimal data
**          can be exported.
[@history_template@]...
*/
DB_STATUS
adc_dbtoev(
ADF_CB             *adf_scb,
DB_DATA_VALUE      *db_value,
DB_DATA_VALUE	   *ev_value)
{
    DB_DT_ID            bdt = abs(db_value->db_datatype);
    DB_DT_ID		bdtv;
    DB_STATUS		status = E_DB_OK;

    bdtv = ADI_DT_MAP_MACRO(bdt);
    if (    bdtv <= 0 || bdtv > ADI_MXDTS
	 || Adf_globs->Adi_dtptrs[bdtv] == NULL
       )
	return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));

    if (Adf_globs->Adi_dtptrs[bdtv]->adi_dtstat_bits &
		(AD_NOEXPORT | AD_CONDEXPORT))
    {
	if( bdt == DB_DEC_TYPE)
	{
	    if(adf_scb->adf_proto_level & AD_DECIMAL_PROTO)
	    {
		ev_value->db_datatype = db_value->db_datatype;
		ev_value->db_length = db_value->db_length;
		ev_value->db_prec = db_value->db_prec;		
		ev_value->db_collID = db_value->db_collID;		
	    }
	    else
		return(adu_error(adf_scb, E_AD101A_DT_NOT_SUPPORTED, 2,
				(i4) sizeof(SystemProductName),
				(i4 *) &SystemProductName));
	}
	else
	{
	    if (Adf_globs->Adi_dtptrs[bdtv]->adi_dt_com_vect.adp_dbtoev_addr)
	    {
		if (db_value->db_datatype >= 0)
		{
		    status = (*Adf_globs->Adi_dtptrs[bdtv]->
			      adi_dt_com_vect.adp_dbtoev_addr)
			      (adf_scb, db_value, ev_value);
		}
		else
		{
		    DB_DATA_VALUE	    tmp_db;
		    DB_DATA_VALUE	    tmp_ev;
		    
		    /* Datatype is nullable -- adjust length & datatype for */
		    /* underlying code	                                    */

		    tmp_db.db_length = db_value->db_length - 1;
		    tmp_db.db_prec = db_value->db_prec;
		    tmp_db.db_collID = db_value->db_collID;
		    tmp_db.db_datatype = bdt;
		    status = (*Adf_globs->Adi_dtptrs[bdtv]->
			      adi_dt_com_vect.adp_dbtoev_addr)
			       (adf_scb, &tmp_db, &tmp_ev);
		    ev_value->db_datatype = -(abs(tmp_ev.db_datatype));
		    ev_value->db_length = tmp_ev.db_length + 1;
		    ev_value->db_prec = tmp_ev.db_prec;
		    ev_value->db_prec = tmp_ev.db_collID;
		}
	    }
	    else
	    {
		return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    }
	}
    }
    else
    {
	status = E_DB_WARN;
	STRUCT_ASSIGN_MACRO(*db_value, *ev_value);
    }
    return(status);
}
Exemplo n.º 24
0
DB_STATUS
adu_dbmsinfo(
ADF_CB             *adf_scb,
DB_DATA_VALUE      *dv1,
DB_DATA_VALUE      *rdv)
{
    i4			i = Adf_globs->Adi_num_dbis;
    i4			found = FALSE;
    ADF_DBMSINFO	*dbi = Adf_globs->Adi_dbi;
    i4			dbi_size = sizeof(dbi->dbi_reqname);
    i4			in_size  = ((DB_TEXT_STRING *)dv1->db_data)->db_t_count;
    char		*in_str  = (char *)
				    ((DB_TEXT_STRING *)dv1->db_data)->db_t_text;
    register i4	j;
    register char	*c1;
    register char	*c2;
    char		ch_tmp;
    ALIGN_RESTRICT	*tbuf;
    DB_STATUS		db_stat = E_DB_OK;
    i4			cmp;
    DB_DATA_VALUE	tmp_dv;
    DB_ERROR		err;
    ADK_MAP		*kmap;
    char		localbuf[2004];
    bool		uselocal = TRUE;


    if (in_size <= dbi_size)    /* No possible match if input is bigger */
    {
	/* Find the request in the dbmsinfo() request table */
	while (i--)
	{
	    cmp = TRUE;
	    c1  = dbi->dbi_reqname;
	    c2  = in_str;
	    j   = 0;
	    while (j < in_size  &&  *c1 != 0)
	    {
		CMtolower(c2, &ch_tmp);
		if (*c1 != ch_tmp)
		{
		    cmp = FALSE;
		    break;
		}
		c1++;
		c2++;
		j++;
	    }

	    if (    cmp
		&& (in_size == dbi_size  ||  (*c1 == 0  &&  j == in_size))
	       )
	    {
		found = TRUE;
		break;
	    }

	    dbi++;
	}
    }


    if (!found)
    {
	((DB_TEXT_STRING *)rdv->db_data)->db_t_count = 0;
	db_stat = E_DB_OK;
    }
    else
    {
	/* {@fix_me@} ... eventually, we have to handle 1 input, and
	**		    lenspecs that are not FIXED LENGTH
	*/
	if (dbi->dbi_num_inputs || dbi->dbi_lenspec.adi_lncompute != ADI_FIXED)
	    return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));

	tmp_dv.db_datatype = dbi->dbi_dtr;
	tmp_dv.db_length   = dbi->dbi_lenspec.adi_fixedsize;

	if (tmp_dv.db_length >= 2004)
	{
	    uselocal = FALSE;
	    tbuf = (ALIGN_RESTRICT *)MEreqmem(0,
					  ((DB_GW4_MAXSTRING + DB_CNTSIZE - 1) /
					  sizeof(ALIGN_RESTRICT)) + 1,
					  FALSE, NULL);
	    tmp_dv.db_data     = (PTR)tbuf;
	}
	else tmp_dv.db_data     = (PTR)&localbuf[0];

	/*
	** Is request one of the query constants?  If so, use adu_dbconst()
	** instead of the dbi function found in the dbi table.
	*/
	if      (dbi == Adf_globs->Adk_bintim_map.adk_dbi)
	    kmap = &Adf_globs->Adk_bintim_map;
	else if (dbi == Adf_globs->Adk_cpu_ms_map.adk_dbi)
	    kmap = &Adf_globs->Adk_cpu_ms_map;
	else if (dbi == Adf_globs->Adk_et_sec_map.adk_dbi)
	    kmap = &Adf_globs->Adk_et_sec_map;
	else if (dbi == Adf_globs->Adk_dio_cnt_map.adk_dbi)
	    kmap = &Adf_globs->Adk_dio_cnt_map;
	else if (dbi == Adf_globs->Adk_bio_cnt_map.adk_dbi)
	    kmap = &Adf_globs->Adk_bio_cnt_map;
	else if (dbi == Adf_globs->Adk_pfault_cnt_map.adk_dbi)
	    kmap = &Adf_globs->Adk_pfault_cnt_map;
	else if (dbi == Adf_globs->Adk_curr_date_map.adk_dbi)
	    kmap = &Adf_globs->Adk_curr_date_map;
	else if (dbi == Adf_globs->Adk_curr_time_map.adk_dbi)
	    kmap = &Adf_globs->Adk_curr_time_map;
	else if (dbi == Adf_globs->Adk_curr_tstmp_map.adk_dbi)
	    kmap = &Adf_globs->Adk_curr_tstmp_map;
	else if (dbi == Adf_globs->Adk_local_time_map.adk_dbi)
	    kmap = &Adf_globs->Adk_local_time_map;
	else if (dbi == Adf_globs->Adk_local_tstmp_map.adk_dbi)
	    kmap = &Adf_globs->Adk_local_tstmp_map;
	else
	    kmap = NULL;

	if (kmap == NULL)
	    db_stat = (*dbi->dbi_func)(dbi, NULL, &tmp_dv, &err);
	else
	    db_stat = adu_dbconst(adf_scb, kmap, &tmp_dv);
	
	if (DB_SUCCESS_MACRO(db_stat))
	{
	    db_stat = adu_ascii(adf_scb, &tmp_dv, rdv);
	}

	if (!uselocal)
	    MEfree((PTR)tbuf);
    }

    return (db_stat);
}
Exemplo n.º 25
0
/*{
** Name: adt_utf8comp() - Compare 2 c/text/char/varchar values in UTF8 server
**
** Description:
**	This routine compares two string data values. Before they are compared,
**	they must be coerced to UCS2 and the comparison is done according to
**	the Unicode Collation Algorithm. This necessitates a call to 
**	adu_nvchr_utf8comp() to perform the setup and comparison. This function
**	presents the values as DB_DATA_VALUE structures, as expected by
**	adu_nvchr_utf8comp().
**
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      atr_bdt				Data type to be compared.
**	atr_len				Length of comparands.
**      d1                        	Pointer to first value.
**      d2                              Pointer to second value.
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      status                          Status returned from
**					adu_mvchr_utf8comp(), if called.
**	
**	    The following DB_STATUS codes may be returned by 
**	    adu_nvchr_utf8comp():
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	    If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**          E_AD0000_OK                 Operation succeeded.
**          E_AD2004_BAD_DTID           Datatype id unknown to ADF.
**          E_AD2005_BAD_DTLEN          Internal length is illegal for
**					the given datatype.
**		(Others not yet defined)
**
** Returns:
**      i4  < 0   if 1st < 2nd
**          = 0   if 1st = 2nd
**          > 0   if 1st > 2nd
**
** Exceptions:
**       none
**
** Side Effects:
**       none
**
** History:
**      10-may-2007 (dougi)
**	    Written for UTF8-enabled server.
**	05-nov-2007 (gupsh01)
**	    pass in default for quel pattern matching to 
**	    adu_nvchr_utf8comp.
**	19-mar-2008 (gupsh01)
**	    Use an aligned buffer for varchar and text types.
**	20-mar-2008 (gupsh01)
**	    Start with an aligned buffer to work with.
**	12-jul-2008 (gupsh01)
**	    Fix the size allocated for aligned buffer.
*/
static i4
adt_utf8comp(
ADF_CB		    *adf_scb,
DB_ATTS		    *atr,
i4		    atr_bdt,
i2		    atr_len,
char		    *d1,		/* Ptr to 1st value */
char		    *d2,		/* Ptr to 2nd value */
DB_STATUS	    *status)		/* Status from adc_compare */

{
    i4			cur_cmp;	/* Result of latest attr cmp */
    DB_DATA_VALUE	dv1;
    DB_DATA_VALUE	dv2;
    ALIGN_RESTRICT      temp_dv1[2048 / sizeof(ALIGN_RESTRICT)];
    ALIGN_RESTRICT      temp_dv2[2048 / sizeof(ALIGN_RESTRICT)];
    char		*dv1data = d1;
    char		*dv2data = d2;
    u_char		*tc1, *tc2, *dc1, *dc2;
    bool		getdv1mem = FALSE;
    bool		getdv2mem = FALSE;
    i4			reqlen;

    /* If varchar/text then use the aligned buffer */
    if ((abs(atr_bdt) == DB_VCH_TYPE) ||
        (abs(atr_bdt) == DB_TXT_TYPE))
    {
        STATUS		stat;
	/*
        ** Check for alignment
        */
	reqlen = atr_len + DB_CNTSIZE + sizeof(ALIGN_RESTRICT);
        if(ME_ALIGN_MACRO((PTR)d1, sizeof(ALIGN_RESTRICT)) !=d1)
	{
	  if (reqlen > sizeof(temp_dv1))
	  {
	    dv1data = (char *)MEreqmem(0, reqlen, FALSE, &stat);
	    if ((dv1data == NULL) || (stat != OK))
	      return (adu_error(adf_scb, E_AD2042_MEMALLOC_FAIL, 2, 0, 
			(i4) sizeof(stat), (i4 *)&stat));
            getdv1mem = TRUE;
	  }
	  else
	    dv1data = (char *)&temp_dv1[0];
	  
    	  I2ASSIGN_MACRO(((DB_TEXT_STRING *)d1)->db_t_count, 
			 ((DB_TEXT_STRING *)dv1data)->db_t_count); 
          tc1 = (u_char *)d1 + DB_CNTSIZE;
	  dc1 = (u_char *)dv1data + DB_CNTSIZE; 
	  MEcopy ( tc1, atr_len, dc1);
	}

        if(ME_ALIGN_MACRO((PTR)d2, sizeof(ALIGN_RESTRICT)) !=d2)
	{
	  if (reqlen > sizeof(temp_dv2))
	  {
	    dv2data = (char *)MEreqmem(0, reqlen , FALSE, &stat);
	    if ((dv2data == NULL) || (stat != OK))
	      return (adu_error(adf_scb, E_AD2042_MEMALLOC_FAIL, 2, 0, 
			(i4) sizeof(stat), (i4 *)&stat));
            getdv2mem = TRUE;
	  }
	  else
	    dv2data = (char *)&temp_dv2[0];

    	  I2ASSIGN_MACRO(((DB_TEXT_STRING *)d2)->db_t_count, 
			 ((DB_TEXT_STRING *)dv2data)->db_t_count); 
          tc2 = (u_char *)d2 + DB_CNTSIZE;
	  dc2 = (u_char *)dv2data + DB_CNTSIZE; 
	  MEcopy ( tc2, atr_len, dc2);
	}
    }

    /* Set up DB_DATA_VALUEs. */
    dv1.db_datatype = dv2.db_datatype = (DB_DT_ID)atr_bdt;
    dv1.db_prec = dv2.db_prec = atr->precision;
    dv1.db_length = dv2.db_length = atr_len;
    dv1.db_collID = dv2.db_collID = atr->collID;
    dv1.db_data = dv1data;
    dv2.db_data = dv2data;
    *status = adu_nvchr_utf8comp(adf_scb, 0, &dv1, &dv2, &cur_cmp);

    if (getdv1mem && dv1data)
	  MEfree (dv1data);

    if (getdv2mem && dv2data)
	  MEfree (dv2data);

    return(cur_cmp);
}
Exemplo n.º 26
0
DB_STATUS
adu_like_all(
	ADF_CB		*adf_scb,
	DB_DATA_VALUE	*src_dv,
	DB_DATA_VALUE	*pat_dv,
	DB_DATA_VALUE	*esc_dv,
	u_i4		pat_flags,
	i4		*rcmp)
{
    DB_STATUS db_stat = E_DB_OK;
    AD_PAT_SEA_CTX _sea_ctx;
    AD_PAT_SEA_CTX *sea_ctx = &_sea_ctx;
    AD_PATDATA _patdata;
    AD_PATDATA *patdata;
    AD_PAT_DA_CTX da_ctx;
    DB_DATA_VALUE dv_tmp1;
    DB_DATA_VALUE dv_tmp2;
    DB_DATA_VALUE *s1 = src_dv, *p1 = pat_dv;
    i4 rcmp1 = 0;
    i4 long_seen = 0;
    DB_STATUS db_stat1 = E_DB_OK;
    char tmp[2000];
    i2 saved_uninorm_flag = adf_scb->adf_uninorm_flag;
    static struct {
	ADU_PATCOMP_FUNC *compile;
	ADU_PATEXEC_FUNC *execute;
    } rtns[] = {
	{adu_patcomp_like,     adu_pat_execute},
	{adu_patcomp_like,     adu_pat_execute_col},
	{adu_patcomp_like_uni, adu_pat_execute_uni},
    };
    enum rtns_idx {
	LIKE, LIKE_COLLATION, LIKE_UNICODE 
    } form = LIKE;
    
    if (pat_dv->db_datatype == DB_PAT_TYPE)
    {
	patdata = (AD_PATDATA*)pat_dv->db_data;
	if (ME_ALIGN_MACRO(patdata, sizeof(i2)) != (PTR)patdata)
	{
	    if ((i2)sizeof(_patdata) >= pat_dv->db_length)
		patdata = &_patdata;
	    else
	    {
		patdata = (AD_PATDATA*)MEreqmem(0, pat_dv->db_length,
			    FALSE, &db_stat);
		if (!patdata || db_stat)
		    return db_stat;
	    }
	    MEcopy(pat_dv->db_data, pat_dv->db_length, patdata);
	}
	pat_flags = patdata->patdata.flags|
		    (patdata->patdata.flags2<<16);
	/* Pre-compiled pattern */
	{
	    i4 i;
	    /* ->patdata is passed in preset with a valid [PATDATA_LENGTH] -
	    ** save it now as we will clear the lot */
	    MEfill(sizeof(*sea_ctx), 0, (PTR)sea_ctx);
	    sea_ctx->patdata = patdata;
	    /*sea_ctx->buffer = NULL;*/
	    /*sea_ctx->bufend = NULL;*/
	    /*sea_ctx->buftrueend = NULL;*/
	    /*sea_ctx->seg_offset = 0;*/
	    /*sea_ctx->buflen = 0;*/
	    /*sea_ctx->at_bof = FALSE;*/
	    /*sea_ctx->at_eof = FALSE;*/
	    /*sea_ctx->trace = FALSE;*/
	    /*sea_ctx->force_fail = FALSE;*/
	    /*sea_ctx->cmplx_lim_exc = FALSE;*/
	    /*sea_ctx->stalled = NULL;*/
	    /*sea_ctx->pending = NULL;*/
	    /*sea_ctx->free = NULL;*/
	    /*sea_ctx->setbuf = NULL;*/
#if PAT_DBG_TRACE>0
	    /*sea_ctx->nid = 0;*/
	    /*sea_ctx->infile = NULL;*/
	    /*sea_ctx->outfile = NULL;*/
#endif
	    /*sea_ctx->nctxs_extra = 0;*/
	    sea_ctx->nctxs = DEF_THD;
	    for (i = DEF_THD-1; i >= 0; i--)
	    {
		sea_ctx->ctxs[i].next = sea_ctx->free;
		sea_ctx->free = &sea_ctx->ctxs[i];
	    }
	}
	db_stat = adu_patcomp_set_pats(sea_ctx);

	/* If prior patcomp flagged force_fail - obey it */
	if (patdata->patdata.flags2 & AD_PAT2_FORCE_FAIL)
	    sea_ctx->force_fail = TRUE;
    }
    else
    {
	patdata = &_patdata;
	/* Tell compiler size we are prepared for */
	patdata->patdata.length = sizeof(_patdata)/sizeof(_patdata.vec[0]);
	sea_ctx->patdata = patdata;
	/*
	** To allow for default processing we have the user specified
	** case flags to deal with. If AD_PAT_WITH_CASE or AD_PAT_WO_CASE
	** is set then we use that setting to override any collation
	** case request. If neither are set we obey the collation.
	*/
	if (pat_flags & AD_PAT_WITH_CASE)
	{
	    pat_flags &= ~AD_PAT_WO_CASE;
	}
	else if (!(pat_flags & AD_PAT_WO_CASE) &&
		(src_dv->db_collID == DB_UNICODE_CASEINSENSITIVE_COLL ||
		pat_dv->db_collID == DB_UNICODE_CASEINSENSITIVE_COLL))
	{
	    pat_flags |= AD_PAT_WO_CASE;
	}
	/*
	** From this point on, the AD_PAT_WITH_CASE flag is ignored as
	** its state has been folded into the AD_PAT_WO_CASE flag.
	*/
    }

    if (ADU_pat_legacy == -1)
	pat_flags &= ~AD_PAT_WO_CASE;
    else if (ADU_pat_legacy == -2)
	pat_flags |= AD_PAT_WO_CASE;

    dv_tmp1.db_data = NULL;
    dv_tmp2.db_data = NULL;

    switch (abs(src_dv->db_datatype))
    {
    case DB_LNVCHR_TYPE:
    case DB_LNLOC_TYPE:
	long_seen = 1;
    case DB_NVCHR_TYPE:
    case DB_NCHR_TYPE:
    case DB_UTF8_TYPE:
    case DB_NQTXT_TYPE:
	form = LIKE_UNICODE;
	/* All handled directly by DA */
	break;
    case DB_LVCH_TYPE:
    case DB_LCLOC_TYPE:
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	    form = LIKE_UNICODE;
    case DB_LBYTE_TYPE:
    case DB_LBLOC_TYPE:
	long_seen = 1;
    case DB_BYTE_TYPE:
    case DB_VBYTE_TYPE:
	/* All handled directly by DA */
	break;
    case DB_CHR_TYPE:
	pat_flags |= AD_PAT_BIGNORE;	/* Ignore blanks */
	/*FALLTHROUGH*/
    case DB_CHA_TYPE:
    case DB_VCH_TYPE:
    case DB_TXT_TYPE:
    case DB_LTXT_TYPE:
	if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
	{
	    form = LIKE_UNICODE;
	    dv_tmp1.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp1.db_length = src_dv->db_length * 4 + DB_CNTSIZE;
	    dv_tmp1.db_prec = 0;
	    dv_tmp1.db_collID = -1;
	    if (dv_tmp1.db_length < (i2)sizeof(tmp))
		dv_tmp1.db_data = tmp;
	    else
	    {
		dv_tmp1.db_data = (char *) MEreqmem (0, dv_tmp1.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
            adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
	    db_stat = adu_nvchr_fromutf8(adf_scb, src_dv, &dv_tmp1);
            adf_scb->adf_uninorm_flag = saved_uninorm_flag;
	    src_dv = &dv_tmp1;
	}
	break;
    default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }

    /*
    ** See how the pattern looks and coerce appropriatly
    */
    switch (abs(pat_dv->db_datatype))
    {
    case DB_LNVCHR_TYPE:
    case DB_LNLOC_TYPE:
	long_seen = 1;
    case DB_NVCHR_TYPE:
    case DB_NCHR_TYPE:
    case DB_UTF8_TYPE:
    case DB_NQTXT_TYPE:
	if (form != LIKE_UNICODE)
	{
	    DB_DATA_VALUE dv_tmp3;
	    form = LIKE_UNICODE;
	    dv_tmp1.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp1.db_length = src_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp1.db_prec = 0;
	    dv_tmp1.db_collID = -1;
	    dv_tmp3.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp3.db_length = src_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp3.db_prec = 0;
	    dv_tmp3.db_collID = -1;
	    if (dv_tmp1.db_length < (i2)sizeof(tmp))
		dv_tmp1.db_data = tmp;
	    else
	    {
		dv_tmp1.db_data = (char *) MEreqmem (0, dv_tmp1.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
	    dv_tmp3.db_data = (char *) MEreqmem (0, dv_tmp3.db_length, TRUE, &db_stat);
	    if (db_stat)
		return db_stat;
	    if (db_stat = adu_nvchr_coerce(adf_scb, src_dv, &dv_tmp3))
	    {
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		return db_stat;
	    }

            adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
	    db_stat = adu_unorm(adf_scb, &dv_tmp3, &dv_tmp1);
            adf_scb->adf_uninorm_flag = saved_uninorm_flag;
	    MEfree((char *)dv_tmp3.db_data);
	    if (db_stat)
	    {
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		return db_stat;
	    }
	    src_dv = &dv_tmp1;
	}
	break;
    case DB_CHR_TYPE:
	pat_flags |= AD_PAT_BIGNORE;	/* Ignore blanks */
	/*FALLTHROUGH*/
    case DB_LVCH_TYPE:
    case DB_LCLOC_TYPE:
    case DB_LBYTE_TYPE:
    case DB_LBLOC_TYPE:
    case DB_BYTE_TYPE:
    case DB_VBYTE_TYPE:
    case DB_CHA_TYPE:
    case DB_VCH_TYPE:
    case DB_TXT_TYPE:
    case DB_LTXT_TYPE:
	if (form == LIKE_UNICODE)
	{
	    DB_DATA_VALUE dv_tmp3;
	    dv_tmp2.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp2.db_length = pat_dv->db_length * 4 + DB_CNTSIZE;
	    dv_tmp2.db_prec = 0;
	    dv_tmp2.db_collID = -1;
	    dv_tmp3.db_datatype = DB_NVCHR_TYPE;
	    dv_tmp3.db_length = pat_dv->db_length * 3 + DB_CNTSIZE;
	    dv_tmp3.db_prec = 0;
	    dv_tmp3.db_collID = -1;
	    if (dv_tmp2.db_length < (i2)sizeof(tmp) && dv_tmp1.db_data != tmp)
		dv_tmp2.db_data = tmp;
	    else
	    {
		dv_tmp2.db_data = (char *) MEreqmem (0, dv_tmp2.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
	    }
	    if (adf_scb->adf_utf8_flag & AD_UTF8_ENABLED)
            {
                adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
		db_stat = adu_nvchr_fromutf8(adf_scb, pat_dv, &dv_tmp2);
                adf_scb->adf_uninorm_flag = saved_uninorm_flag;
            }
	    else
	    {
		dv_tmp3.db_data = (char *) MEreqmem (0, dv_tmp3.db_length, TRUE, &db_stat);
		if (db_stat)
		    return db_stat;
		if (db_stat = adu_nvchr_coerce(adf_scb, pat_dv, &dv_tmp3))
		{
		    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
			MEfree((char *)dv_tmp2.db_data);
		    return db_stat;
		}
                adf_scb->adf_uninorm_flag = AD_UNINORM_NFC;
		db_stat = adu_unorm(adf_scb, &dv_tmp3, &dv_tmp2);
                adf_scb->adf_uninorm_flag = saved_uninorm_flag;
		MEfree((char *)dv_tmp3.db_data);
		if (db_stat)
		{
		    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
			MEfree((char *)dv_tmp2.db_data);
		    return db_stat;
		}
	    }
	    pat_dv = &dv_tmp2;
	}
	break;
    case DB_PAT_TYPE:
	if (patdata->patdata.flags2 & AD_PAT2_UNICODE)
	    form = LIKE_UNICODE;
	else if (patdata->patdata.flags2 & AD_PAT2_COLLATE)
	    form = LIKE_COLLATION;
	break;
    default:
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }

    if (abs(pat_dv->db_datatype) != DB_PAT_TYPE)
    {
	if (form == LIKE && adf_scb->adf_collation)
	{
	    form = LIKE_COLLATION;
	    pat_flags |= (AD_PAT2_COLLATE<<16);
	}
	else if (form == LIKE_UNICODE)
	    pat_flags |= (AD_PAT2_UNICODE<<16);

	if (ADU_pat_legacy > 0 &&
		    !long_seen &&
		    (pat_flags & AD_PAT_FORM_MASK) == AD_PAT_FORM_LIKE)
	{
	    if (form == LIKE_UNICODE)
		db_stat1 = adu_ulike(adf_scb, s1, p1,
			(UCS2*)(esc_dv?esc_dv->db_data:0), &rcmp1);
	    else
		db_stat1 = adu_like(adf_scb, s1, p1,
			(u_char*)(esc_dv?esc_dv->db_data:0), &rcmp1);
	    if (ADU_pat_legacy == 3)
	    {
		/* Look no further */
		*rcmp = rcmp1;
		if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
		    MEfree((char *)dv_tmp1.db_data);
		if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
		    MEfree((char *)dv_tmp2.db_data);
		return db_stat1;
	    }
	}

	/* Compile the input pattern */
	db_stat = (rtns[form].compile)(adf_scb, pat_dv, esc_dv, pat_flags, sea_ctx);
    }
    if (!db_stat && sea_ctx)
    {
	if (sea_ctx->force_fail)
	    *rcmp = 1;
	else
	{
	    /* Init the data access */
	    if (!(db_stat = adu_patda_init(adf_scb, src_dv, sea_ctx, &da_ctx)))
	    {
		/* Do the search */
		db_stat = (rtns[form].execute)(sea_ctx, &da_ctx, rcmp);
	    }
	    /* Cleanup the data access */
	    (VOID)adu_patda_term(&da_ctx);
	    if (!db_stat && sea_ctx->cmplx_lim_exc)
		db_stat = adu_error(adf_scb, E_AD1026_PAT_TOO_CPLX, 0);
        }
    }
    adu_patcomp_free(sea_ctx);

    if (dv_tmp1.db_data && dv_tmp1.db_data != tmp)
	MEfree((char *)dv_tmp1.db_data);
    if (dv_tmp2.db_data && dv_tmp2.db_data != tmp)
	MEfree((char *)dv_tmp2.db_data);
    if (patdata != &_patdata && (PTR)patdata != pat_dv->db_data)
	MEfree((PTR)patdata);

    if (ADU_pat_legacy > 0 &&
		!long_seen &&
		(pat_flags & AD_PAT_FORM_MASK) == AD_PAT_FORM_LIKE)
    {
	if (db_stat1 && db_stat)
	{
	    /* Old unsupported? - just report */
	    TRdisplay("%s old fail - %d %d osts=%d nsts=%d\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat1, db_stat);
	}
	else if (db_stat1 && !db_stat)
	{
	    /* NEW SOLUTION - */
	    TRdisplay("%s new support - %d %d osts=%d\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat1);
	}
	else if (!db_stat1 && db_stat)
	{
	    i4 sl, pl;
	    char *s, *p;
	    /*NEW PROB - report & fixup */
	    adu_lenaddr(adf_scb, s1, &sl, &s);
	    adu_lenaddr(adf_scb, p1, &pl, &p);
	    TRdisplay("%s new problem - %d %d nsts=%d ores=%d nres=%d '%.#s' '%.#s'\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		db_stat,
		rcmp1, *rcmp,
		sl,s,pl,p);
	    if (ADU_pat_legacy > 1)
	    {
		*rcmp = rcmp1;
		db_stat = db_stat1;
	    }
	}
	else if (*rcmp != rcmp1)
	{
	    i4 sl, pl;
	    char *s, *p;
	    /*NEW PROB - report & fixup */
	    adu_lenaddr(adf_scb, s1, &sl, &s);
	    adu_lenaddr(adf_scb, p1, &pl, &p);
	    TRdisplay("%s bad? %d %d ores=%d nres=%d '%.#s' '%.#s'\n",
		pat_flags & AD_PAT_WO_CASE?"ILIKE":"LIKE",
		s1->db_datatype, p1->db_datatype,
		rcmp1, *rcmp,
		sl,s,pl,p);
	    if (ADU_pat_legacy > 1)
	    {
		*rcmp = rcmp1;
		db_stat = db_stat1;
	    }
	}
    }
    return db_stat;
}
Exemplo n.º 27
0
/*
** {
** Name: adu_redeem	- Redeem an ADF_COUPON
**
** Description:
**      This routine redeems an ADF_COUPON, i.e. it materializes the object
**	represented by the coupon.  Since objects represented by coupons
**	may not fit in memory, this routine must deal with returning partial
**	results.  In such cases, it will store its partial status in its fourth
**	argument, which is to be returned for each call. 
**
** Inputs:
**      adf_scb                  Standard ADF session control block
**      result_dv                Ptr to DB_DATA_VALUE into which to
**                               place the result.
**      coupon_dv                Ptr to DB_DATA_VALUE which contains
**                               the input to redeem.
**      workspace_dv             Ptr to DB_DATA_VALUE which points to
**                               the workspace.  This workspace is
**                               expected to be maintained across
**                               calls to this routine for any given
**                               coupon.  (I.e. it can be "new" only
**                               when "continuation" (next param) is
**                               zero.
**      continuation             Is this a continuation of a previous
**                               call.
**
** Outputs:
**      adf_scb->adf_errcb       Filled as appropriate.
**      result_dv->db_length     Filled with the length of the result
**                               area actually used.
**      *workspace->db_data      Filled with info to be used by
**                               subsequent invocations of this routine.
**	Returns:
**          E_DB_ERROR           In case of error
**          E_DB_INFO/E_AD0002_INCOMPLETE
**                               When more calls are necessary
**          E_DB_OK              When complete.
**
**	Exceptions:
**	    None.
**
** Side Effects:
**	    None.
**
** History:
**      07-dec-1989 (fred)
**          Prototyped.
**      06-oct-1992 (fred)
**          Altered to work with timezone integration.  As a temporary measure,
**	    this routine was using the ADF_CB.adf_4rsvd field to store
**	    some context across calls.  In that this field disappeared, a new,
**	    more appropriately named field was added (adf_lo_context).  This
**	    new ADF_CB field is now used in this file.
**	30-Oct-1992 (fred)
**	    Fixed to correctly handle being called with a length too short
**	    for the original header.
**	20-Nov-1992 (fred)
**	    Rewritten for better clarity & better delineation of
**	    function in support of OME large objects.
**      18-Oct-1993 (fred)
**          Moved check for FEXI function so that STAR, which has
**          none, can send null blobs sometimes.  It helps get a tiny
**          bit of support in to STAR.
**      13-Apr-1994 (fred)
**          Altered to hand status from FEXI call straight back.  By
**          not losing the actual status, interrupts may avoid logging
**          too much stuff.
**      14-Sep-1995 (shust01/thaju02)
**          fixed problem of endless loop when we are finished, but we
**	    come in just to get the NULL byte.  work->adw_shared.shd_o_used 
**	    had old size (which was max value), so we never end.  Set
**	    work->adw_shared.shd_o_used = 0.
**	24-Oct-2001 (thaju02)
**	    If adc_lvch_xform() was unable to fit the 2-byte segment
**	    length in the result buffer, decrement result length
**	    with unused byte and flush segment. (B104122)
[@history_template@]...
*/
DB_STATUS
adu_redeem(
ADF_CB            *adf_scb,
DB_DATA_VALUE	   *result_dv,
DB_DATA_VALUE      *coupon_dv,
DB_DATA_VALUE      *workspace_dv,
i4            continuation)
{
    ADP_LO_WKSP 	*work = (ADP_LO_WKSP *) workspace_dv->db_data;
    DB_DT_ID		dtid;
    ADP_PERIPHERAL	*p = (ADP_PERIPHERAL *) result_dv->db_data;
    DB_STATUS		status;
    i4			done = FALSE;
    i4                  flush;
    i4			for_gca = 1;
    i4                  loop_around;

    if (result_dv->db_datatype != coupon_dv->db_datatype)
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	
    dtid = ADI_DT_MAP_MACRO(abs(result_dv->db_datatype));
    if (    dtid <= 0
	 || dtid  > ADI_MXDTS
	 || Adf_globs->Adi_dtptrs[dtid] == NULL
	 || !Adf_globs->Adi_dtptrs[dtid]->adi_under_dt
       )
	return(adu_error(adf_scb, E_AD2004_BAD_DTID, 0));

    if ((!continuation) || (work->adw_fip.fip_state == ADW_F_STARTING))
    {
	if (!continuation)
	    work->adw_fip.fip_state = ADW_F_INITIAL;
	status = adu_rdm1_setup(adf_scb, result_dv, coupon_dv, work, for_gca);
	if (status || work->adw_fip.fip_done)
	    return(status);
    }
    else if (work->adw_fip.fip_state == ADW_F_DONE_NEED_NULL)
    {
	/*
	**  This is an indication that we finished, but didn't
	**  send the NULL byte, and must do so now...
	*/
	
	work->adw_shared.shd_o_used = 0;
	status = adu_rdm2_finish(adf_scb, result_dv, coupon_dv, work, for_gca);
	return(status);
    }
    else
    {
	if (Adf_globs->Adi_fexi[ADI_01PERIPH_FEXI].adi_fcn_fexi == NULL)
	    return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	work->adw_shared.shd_o_used = 0;
	work->adw_shared.shd_o_length = result_dv->db_length;
	work->adw_shared.shd_o_area = (char *) result_dv->db_data;
	work->adw_fip.fip_pop_cb.pop_continuation = 0;

	work->adw_fip.fip_pop_cb.pop_coupon = coupon_dv;
    }

    for (flush = 0;
	    !done
		&& (!flush)
		&& (work->adw_shared.shd_l1_check <
		    	    	    	work->adw_fip.fip_l1_value);
	/* No update action */)
    
    {
	switch (work->adw_shared.shd_exp_action)
	{
	case ADW_FLUSH_SEGMENT:
	case ADW_START:
	    if (for_gca)
	    {
		/*
		** Since we got a segment back, insert the `here
	        ** comes another segment indicator'.
		*/

		i4		one = 1;

		if ( (work->adw_shared.shd_o_length -
		                         work->adw_shared.shd_o_used)
		       < sizeof(one))
		{
		    /* Then the next segment marker won't fit.  Dump */
		    /* the current segment and move on... */

		    /* fix_me -- better error... */
		
		    return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
		}

		I4ASSIGN_MACRO(one,
		     work->adw_shared.shd_o_area[work->adw_shared.shd_o_used]);
		work->adw_shared.shd_o_used += sizeof(one);
	    }
	    /* Fall thru -- if out of input data, get some */

	case ADW_FLSH_SEG_NOFIT_LIND:
	case ADW_NEXT_SEGMENT:
	    
	    if (   (work->adw_shared.shd_exp_action == ADW_NEXT_SEGMENT)
		&& (work->adw_shared.shd_inp_tag == ADP_P_COUPON))
	    {
		/*
		**  For [DBMS style] coupons, each segment is in a row
		**  unto itself, regardless of the length of the row.
		**  Since this routine is datatype independent, it
		**  cannot tell when a segment is up, and thus must
		**  rely on the called routine.  Thus, if the callee
		**  asks for a new segment when processing a DBMS
		**  coupon, this routine will assume that the current
		**  set of data has been all used up...
		*/

		work->adw_shared.shd_i_used =
		    work->adw_shared.shd_i_length;
	    }

	    /* Fall thru... */

	case ADW_GET_DATA:
	    if (work->adw_shared.shd_i_used == work->adw_shared.shd_i_length)
	    {
		/*
		** If no unmoved segment data, then get some more.
		*/
		
		if (work->adw_fip.fip_done)
		{
		    done = TRUE;
		    status = E_DB_OK;
		}
		else
		{
		    status =
			(*Adf_globs->Adi_fexi[ADI_01PERIPH_FEXI].adi_fcn_fexi)
			    (ADP_GET, &work->adw_fip.fip_pop_cb);
		    if (status)
		    {
			if (work->adw_fip.fip_pop_cb.pop_error.err_code
			    == E_AD7001_ADP_NONEXT)
			{
			    work->adw_fip.fip_done = TRUE;
			    
			    if (status == E_DB_WARN)
				status = E_DB_OK;
			    else
				break;
			}
			else
			{
			    return(adu_error(adf_scb,
				   work->adw_fip.fip_pop_cb.pop_error.err_code,
					     0));
			}
		    }
		    
		    work->adw_shared.shd_i_used = 0;
		    work->adw_shared.shd_i_length =
			work->adw_fip.fip_seg_dv.db_length;
		    work->adw_shared.shd_i_area =
			work->adw_fip.fip_seg_dv.db_data;

		}
	    }
	    break;

	case ADW_CONTINUE:  /* This shouldn't happen */
	default:            /* Nor should anything else */
	    return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	    break;
	}
	if (done)
	    break;

	status = adc_xform(adf_scb, (PTR)work);
	if (DB_FAILURE_MACRO(status))
	{
	    return(adu_error(adf_scb, E_AD7003_ADP_BAD_RECON, 0));
	}
	if (work->adw_shared.shd_exp_action == ADW_FLUSH_SEGMENT)
	{
	    flush = 1;
	}

	/* B104122 */
	if (work->adw_shared.shd_exp_action == ADW_FLSH_SEG_NOFIT_LIND)
	{
	    result_dv->db_length = work->adw_shared.shd_o_used;
	    flush = 1;
	}

	/* B?????? */
	if (work->adw_shared.shd_exp_action == ADW_FLUSH_INCOMPLETE_SEGMENT)
	{
	    result_dv->db_length = work->adw_shared.shd_o_used;
	    work->adw_shared.shd_exp_action = ADW_FLUSH_SEGMENT;
	    flush = 1;
	}

	work->adw_fip.fip_pop_cb.pop_continuation = 0;
    }

    if (work->adw_shared.shd_l1_check == work->adw_fip.fip_l1_value)
    {
	done = TRUE;
    }

    if (work->adw_fip.fip_test_mode)
    {
	work->adw_fip.fip_test_sent += work->adw_shared.shd_o_used;
	
	if ((work->adw_fip.fip_test_length
	         - work->adw_fip.fip_test_sent
	         - work->adw_fip.fip_null_bytes
	         - (for_gca * sizeof(i4)))
	     <= 0)
	{
	    /*
	    **	Then, for test purposes, we've sent all that we can.
	    **	Emulate completion.
	    */

	    work->adw_fip.fip_done = done = TRUE;
	    work->adw_shared.shd_i_used = work->adw_shared.shd_i_length;
	    work->adw_shared.shd_l1_check = work->adw_fip.fip_l1_value;
	    work->adw_shared.shd_o_used = work->adw_fip.fip_test_length
		                             - work->adw_fip.fip_test_sent
		                             - sizeof(i4)    /* end marker */
			                     - work->adw_fip.fip_null_bytes;
	                                        /* null indicator */
	    work->adw_fip.fip_test_sent =
		work->adw_fip.fip_test_length - sizeof(i4)
		                              - work->adw_fip.fip_null_bytes;
	}

    }
    
    if (done && ((work->adw_shared.shd_exp_action == ADW_NEXT_SEGMENT)
		 || (work->adw_shared.shd_exp_action == ADW_FLUSH_SEGMENT)))
    {
	/*
	** If we think we are done and have used all the input,...
	*/

	status = adu_rdm2_finish(adf_scb, result_dv, coupon_dv, work, for_gca);
    }
    else
    {
	/*
	** Otherwise, if we are surpassing the amount of data which
	** be available...
	*/

	if (work->adw_shared.shd_l1_check > work->adw_fip.fip_l1_value)
	{
	    /*
	    ** FIX_ME -- better error message...
	    ** Then we would be sending an inconsistent blob.
	    ** That would be bad.
	    */

	    return(adu_error(adf_scb, E_AD7004_ADP_BAD_BLOB,0));
	}
	adf_scb->adf_errcb.ad_errcode  = E_AD0002_INCOMPLETE;
	status = E_DB_INFO;
    }
    return(status);
}
Exemplo n.º 28
0
/*{
** Name: adu_rdm1_setup	- Setup for Redeem an ADF_COUPON
**
** Description:
**      This routine performs the initialization for the redeeming of
**      a coupon.  This amount primarily to initializing the
**      ADP_LO_WKSP function instance private and shared (adw_fip &
**      adw_shared, respectively).  This routine also moves the
**      appropriate peripheral header into the output area.
**
**      Since this routine moves the peripheral header to the output
**      area, in the case where the original call to this routine has
**      insufficient space for the output header, this routine may be
**      called more than once.  We note this since it is "unusual" for
**      the initialization routine to be called more than one time for
**      an object.  In the case where the original space is of
**      insufficent size, then this routine will return an indication
**      that the output area is full, and will move nothing into it.
**      Thus, this routine considers it a call-protocol error to be
**      called a second time with insufficient space.
**
** Inputs:
**      adf_scb                     The session's control block (ptr).
**      result_dv                   Pointer to DB_DATA_VALUE for
**                                      result.
**      coupon_dv                   Pointer to DB_DATA_VALUE
**                                      describing the input coupon to
**                                      be redeemed.
**      workspace_dv                Pointer to DB_DATA_VALUE
**                                      describing redeem's workspace.
**      continuation                Continuation indicator.  0
**                                      indicates the first call, else
**                                      not the first call.
**
** Outputs:
**      adf_scb->adf_error          Filled as appropriate.
**      *result_dv->db_data         Setup with beginning of peripheral
**                                      data type.
**      *workspace_dv->db_data      Initialized for ongoing redeem work.
**	Returns:
**	    DB_STATUS
**	Exceptions:
**	    None.
**
** Side Effects:
**	    None.
**
** History:
**      02-dec-1992 (fred)
**          Coded.  Created from adu_redeem prototype in support of
**          OME large objects.
**       8-Apr-1993 (fred)
**          Fixed bug in zero length large object handling.  For large
**          objects of zero length which are not nullable, the length
**          should not include the null-value-byte.
**      12-Oct-1993 (fred)
**          Removed call to ADP_INFORMATION -- subsumed by
**          adi_per_under(). 
**      10-sep-1998 (schte01)
**          Modified I4ASSIGN for axp_osf to pass the value, not the address
**          of the value, to be assigned. This worked under the -oldc
**          compiler option and got compile errors under -newc.
**	28-jul-1999 (thaju02)
**	    If the coupon stipulates that the data is not null, then
**	    the minimum result buffer length must be large enough to
**	    hold one byte of data along with all necessary info
**	    (ADP_HDR_SIZE + nextsegmarker(i4) + 2byteseglenindicator
**	    + 1byteofdata). Given a buffer with only 18 bytes of space
**	    available, 12 bytes are filled with peripheral header info
**	    in adu_rdm1_setup and 4 bytes are filled with the next
**	    segment marker in adu_redeem. In adc_lvch_xform, the 2 
**	    byte segment length indicator is initially set to zero 
**	    in the result buffer. If there is no space left in the 
**	    result buffer for segment data, we flush the buffer. In 
**	    the front end, upon receiving this result buffer, the 
**	    next segment marker indicates that there is data following, 
**	    yet the length is zero; terminal monitor infinitely loops. 
**	    (b98104)
**      12-aug-99 (stial01)
**          adu_rdm1_setup() 'blob_work' arg to adi_per_under should be  
**          NULL before redeem.
**      24-may-2000 (stial01)
**          adu_rdm1_setup() clear null indicator if not null (B101656)
**
[@history_template@]...
*/
DB_STATUS static
adu_rdm1_setup(ADF_CB             *adf_scb,
	       DB_DATA_VALUE      *result_dv,
	       DB_DATA_VALUE      *coupon_dv,
	       ADP_LO_WKSP        *work,
	       i4                 for_gca)
{
    DB_STATUS	    	status;  
    ADP_PERIPHERAL      *p = (ADP_PERIPHERAL *) result_dv->db_data;
    DB_DT_ID            dtid =
	ADI_DT_MAP_MACRO(abs(result_dv->db_datatype));
    i4			min_size;
    bool		isnull = 0;

    if (coupon_dv->db_datatype < 0)
	work->adw_fip.fip_null_bytes = 1;
    else
	work->adw_fip.fip_null_bytes = 0;

    if (ult_check_macro(&Adf_globs->Adf_trvect, ADF_011_RDM_TO_V_STYLE,
			&dummy1, &dummy2))
    {
	work->adw_fip.fip_test_mode = 1;
	work->adw_fip.fip_test_length = ADP_TST_VLENGTH +
	                                   work->adw_fip.fip_null_bytes;
	work->adw_fip.fip_test_sent = 0;
    }
    else
    {
	work->adw_fip.fip_test_mode = 0;
    }

    work->adw_shared.shd_exp_action = ADW_START;
    work->adw_fip.fip_done = FALSE;

    /*
    ** Fool the main routine into getting us an input segment.  Make
    ** look like the input segement is all used up.
    */
    
    work->adw_shared.shd_type = coupon_dv->db_datatype;
    work->adw_shared.shd_i_area = (char *) 0;
    work->adw_shared.shd_i_used = work->adw_shared.shd_i_length = 0;

    work->adw_shared.shd_o_used = ADP_HDR_SIZE;
    work->adw_shared.shd_o_length = result_dv->db_length;
    work->adw_shared.shd_o_area = (char *) result_dv->db_data;

    if (work->adw_shared.shd_o_length > MAXI2)
    {
	TRdisplay("adu_rdm1_setup shd_o_length %d MAX %d\n",
		work->adw_shared.shd_o_length, MAXI2);
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }
    work->adw_shared.shd_l0_check = work->adw_shared.shd_l1_check = 0;

    work->adw_fip.fip_pop_cb.pop_continuation = ADP_C_BEGIN_MASK;
    work->adw_fip.fip_pop_cb.pop_user_arg = (PTR) 0;
    
    work->adw_fip.fip_pop_cb.pop_type = (ADP_POP_TYPE);
    work->adw_fip.fip_pop_cb.pop_length = sizeof(ADP_POP_CB);
    work->adw_fip.fip_pop_cb.pop_ascii_id = ADP_POP_ASCII_ID;
    work->adw_fip.fip_pop_cb.pop_temporary = ADP_POP_PERMANENT;
    work->adw_fip.fip_pop_cb.pop_coupon = coupon_dv;
    work->adw_fip.fip_pop_cb.pop_segment = &work->adw_fip.fip_seg_dv;
    work->adw_fip.fip_pop_cb.pop_underdv = &work->adw_fip.fip_under_dv;
    status = adi_per_under(adf_scb,
			   result_dv->db_datatype,
			   &work->adw_fip.fip_under_dv);

    if (status)
    {
	return(adu_error(adf_scb, E_AD7000_ADP_BAD_INFO, 0));
    }

    STRUCT_ASSIGN_MACRO(work->adw_fip.fip_under_dv,
			work->adw_fip.fip_seg_dv);
    work->adw_fip.fip_seg_dv.db_data = (char *) ((char *) work +
						 sizeof(ADP_LO_WKSP));

    if (ADI_ISNULL_MACRO(coupon_dv) ||
       ((((ADP_PERIPHERAL *)coupon_dv->db_data)->per_length0 == 0)
       && (((ADP_PERIPHERAL *) coupon_dv->db_data)->per_length1 == 0))) 
	isnull = 1;

    if (isnull)
	/* hdr + segment indicator + sizeof(null byte) */
        min_size = ADP_HDR_SIZE + sizeof(i4) + work->adw_fip.fip_null_bytes; 
    else	
	/* hdr + segment indicator + segment length + segment single byte */
        min_size = ADP_HDR_SIZE + sizeof(i4) + sizeof(i2) + sizeof(char); 

    if (result_dv->db_length >= min_size)
    {
	if (for_gca)
	    work->adw_shared.shd_out_tag = ADP_P_GCA;
	else
	    work->adw_shared.shd_out_tag = ADP_P_DATA;
	
	I4ASSIGN_MACRO(work->adw_shared.shd_out_tag, p->per_tag);
	
	work->adw_shared.shd_out_segmented =
	    (work->adw_shared.shd_out_tag != ADP_P_DATA);

	I4ASSIGN_MACRO( ((ADP_PERIPHERAL *)
			 coupon_dv->db_data)->per_tag,
		       work->adw_shared.shd_inp_tag);
	work->adw_shared.shd_inp_segmented =
	    (work->adw_shared.shd_inp_tag != ADP_P_DATA);

	I4ASSIGN_MACRO( ((ADP_PERIPHERAL *)
			 coupon_dv->db_data)->per_length0,
		       p->per_length0);
	I4ASSIGN_MACRO(p->per_length0, work->adw_fip.fip_l0_value);
	I4ASSIGN_MACRO(((ADP_PERIPHERAL *)
			coupon_dv->db_data)->per_length1,
		       p->per_length1);
	I4ASSIGN_MACRO(p->per_length1, work->adw_fip.fip_l1_value);
	work->adw_fip.fip_state = ADW_F_RUNNING;
    }
    else if (work->adw_fip.fip_state != ADW_F_STARTING)
    {
	work->adw_fip.fip_state = ADW_F_STARTING;
	result_dv->db_length = 0;
	adf_scb->adf_errcb.ad_errcode = E_AD0002_INCOMPLETE;
	return(E_DB_INFO);
    }
    else
    {
	return(adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
    }

    if (isnull)
    {
	if (work->adw_fip.fip_test_mode)
	{
	    ((DB_TEXT_STRING *) p)->db_t_count = (i2) 0;

	    if (result_dv->db_length >=
		    (work->adw_fip.fip_test_length -
		              work->adw_fip.fip_test_sent))

	    {
		
		result_dv->db_length = work->adw_fip.fip_test_length -
		     work->adw_fip.fip_test_sent;
		work->adw_fip.fip_test_sent = work->adw_fip.fip_test_length;
	    }
	    else
	    {
		work->adw_fip.fip_state = ADW_F_DONE_NEED_NULL;
		work->adw_fip.fip_test_sent += result_dv->db_length;
		adf_scb->adf_errcb.ad_errcode = E_AD0002_INCOMPLETE;
		return(E_DB_INFO);
	    }
	}
	else
	{
	    i4	    zero = 0;

	    /*
	    **  Insert GCA mark that says there is no segment.
	    */
	
#if defined(axp_osf) || defined(ris_u64) || defined(LP64) || \
    defined(axp_lnx)
	    /*
	    **	We want to init the GCA field after the header, but
	    **	on axp_osf this is not the same as the start of the
	    **	coupon, because 8-byte alignment causes a slack 4-byte
	    **	integer to be between the header and the coupon.  See
	    **	adu_redeem above for a different way this field is set
	    **	to 1 when we have real data (not null).  The addressing
	    **	of this field should really be standardized in such a
	    **	way that contiguous layout of 4-byte aligned fields is
	    **	not assumed.
	    */
            I4ASSIGN_MACRO(zero,*((char *)p + ADP_HDR_SIZE)); 
#endif
	    I4ASSIGN_MACRO(zero, p->per_value);
	    
	    result_dv->db_length = ADP_NULL_PERIPH_SIZE;
	    if (work->adw_shared.shd_type > 0)
		result_dv->db_length -= 1;
        }
	if (ADI_ISNULL_MACRO(coupon_dv))
	    ADF_SETNULL_MACRO(result_dv);
	else
	    ADF_CLRNULL_MACRO(result_dv);
	adf_scb->adf_errcb.ad_errcode = E_DB_OK;
	work->adw_fip.fip_done = TRUE;
	return(E_DB_OK);
    }

    if (work->adw_fip.fip_test_mode)
    {
	i4	    	segment_count;
	i4	    	length1;
	i2		count;
	
	I4ASSIGN_MACRO(p->per_length1, length1);
	
	I4ASSIGN_MACRO(p->per_length0, segment_count);
	
	if (!segment_count)
	    segment_count = ADP_TST_SEG_CNT;
	
	count = min(	ADP_TST_VLENGTH,
		    (i2) (length1
			  + (segment_count *
			     (sizeof(i4) + sizeof(i2)))
			  + sizeof(i4) /* no more segments */
			  + work->adw_shared.shd_o_used)
		    ) - sizeof(i2);
	I2ASSIGN_MACRO(count, ((DB_TEXT_STRING *) p)->db_t_count);
    }
    return(E_DB_OK);
}
Exemplo n.º 29
0
DB_STATUS
ad0_llike(
ADF_CB		    *adf_scb,
register ADULcstate *sst,
u_char		    *ends,
register ADULcstate *pst,
u_char		    *endp,
ADULcstate	    *est,
bool		    bignore,
i4		    *rcmp)
{
    i4			cc;	/* the `character class' for pch */
    i4			stat;
    u_char		match;  /* the untranslated character */

    for (;;)	/* loop through pattern string */
    {
	int count = 0;
	DB_STATUS (*llkmatch)(ADF_CB *,ADULcstate *,u_char*,ADULcstate*,u_char*,
	                      ADULcstate*,bool,i4,i4*) = ad0_llkpmatch;
	/*
	** Get the next character from the pattern string,
	** handling escape sequences, and ignoring blanks if required.
	** -----------------------------------------------------------
	*/
	if (adulptr(pst) >= endp)
	{
	    /* end of pattern string */
	    cc = AD_CC6_EOS;
	}
	else
	{
	    if (est != NULL && !adulcmp(pst, est))
	    {
		adulnext(pst);
		/* we have an escape sequence */
		if (adulptr(pst) >= endp)
		{
		    /* ERROR:  escape at end of pattern string not allowed */
		    return (adu_error(adf_scb, E_AD1017_ESC_AT_ENDSTR, 0));
		}
		match = *(pst->lstr);
		_VOID_ adultrans(pst); /* increment pointer, ignore return */
		switch (match) /* the RAW character value */
		{
		  case AD_1LIKE_ONE:
		  case AD_2LIKE_ANY:
		  case '-':
		    cc = AD_CC0_NORMAL;
		    break;

		  case AD_3LIKE_LBRAC:
		    cc = AD_CC4_LBRAC;
		    break;

		  case AD_4LIKE_RBRAC:
		    cc = AD_CC5_RBRAC;
		    break;

		  default:
		    if (!adulcmp(pst, est))
			cc = AD_CC0_NORMAL;
		    else
			/* ERROR:  illegal escape sequence */
			return (adu_error(adf_scb, E_AD1018_BAD_ESC_SEQ, 0));
		    break;
		}
	    }
	    else
	    {
		/* not an escape character */
		match = *(pst->lstr);
		_VOID_ adultrans(pst); /* increment pointer, ignore return */
		switch (match) /* the RAW character value */
		{
		  case AD_1LIKE_ONE:
		    cc = AD_CC2_ONE;
		    break;

		  case AD_2LIKE_ANY:
		    cc = AD_CC3_ANY;
		    break;

		  case '-':
		    cc = AD_CC1_DASH;
		    break;

		  case AD_3LIKE_LBRAC:
		  case AD_4LIKE_RBRAC:
		  default:
		    cc = AD_CC0_NORMAL;
		    break;
		}
	    }
	}

	if (	bignore
	    &&	cc == AD_CC0_NORMAL
	    &&	(adulspace(pst)  || adulisnull(pst))
	   )
	{
	    adulnext(pst);
	    continue;	/* ignore blanks and null chars for the C datatype */
	}


	/* Now we have the next pattern string character and its class */
	/* ----------------------------------------------------------- */

	switch (cc)
	{
	  case AD_CC0_NORMAL:
	  case AD_CC1_DASH:
	    for (;;)
	    {
		if (adulptr(sst) >= ends)
		{
		    *rcmp = -1;	/* string is shorter than pattern */
		    return (E_DB_OK);
		}
		if (!bignore  ||  (!adulspace(sst)  && !adulisnull(sst)))
		    break;
		    
		adulnext(sst);
	    }

	    if ((stat = adulcmp(sst, pst)) != 0)
	    {
		*rcmp = stat;
		return (E_DB_OK);
	    }
	    break;

	  case AD_CC2_ONE:
		count = 1;
		adulnext(pst);
		llkmatch = ad0_llkqmatch;
		/*FALLTHROUGH*/
	  case AD_CC3_ANY:
	    while (adulptr(pst) < endp)
	    {
		match = *(pst->lstr);
		if (match == AD_1LIKE_ONE)
		{
		    _VOID_ adultrans(pst); /* increment pointer, ignore return */
		    count++;
		}
		else if (match == AD_2LIKE_ANY)
		{
		    _VOID_ adultrans(pst); /* increment pointer, ignore return */
		    llkmatch = ad0_llkpmatch;
		}
		else if (!bignore || !adulspace(pst) && !adulisnull(pst))
		    break;
		adulnext(pst);
	    }
	    return llkmatch(adf_scb, sst, ends, pst, endp,
					est, bignore, count, rcmp);

	  case AD_CC4_LBRAC:
	    return (ad0_llklmatch(adf_scb, sst, ends, pst, endp,
					est, bignore, rcmp));

	  case AD_CC5_RBRAC:
	    /*
	    ** ERROR:  bad range specification.
	    */
	    return (adu_error(adf_scb, E_AD1015_BAD_RANGE, 0));

	  case AD_CC6_EOS:
	    /*
	    ** End of pattern string.  Check for rest of other string.
	    */
	    while (adulptr(sst) < ends)
	    {
		if (!bignore  ||  (!adulspace(sst)  && !adulisnull(sst)))
		{
		    *rcmp = 1;	    /* string is longer than pattern */
		    return (E_DB_OK);
		}
		adulnext(sst);
	    }
	    *rcmp = 0;
	    return (E_DB_OK);

	  default:
	    /*
	    ** ERROR:  should *NEVER* get here.
	    */
	    return (adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0));
	}
	adulnext(pst);
    	adulnext(sst);

    }
}
Exemplo n.º 30
0
/*{
** Name: adc_1dbtoev_ingres	- Dbtoev for Ingres datatypes
**
** Description:
**      This routine, given an input datatype, determines which type to send to
**	output.  It is assumed that a coercion exists for this datatype
**	transformation.
**
**	If the datatype is exportable (AD_NOEXPORT is not set), then the result
**	datatype is identical with the input.  Otherwise, a call is made to the
**	dbtoev routine specified in the datatype com vector. 
**
**	If the input is nullable, then the output is nullable as well. 
**
** Inputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.
**		.ad_ebuflen		The length, in bytes, of the buffer
**					pointed to by ad_errmsgp.
**		.ad_errmsgp		Pointer to a buffer to put formatted
**					error message in, if necessary.
**      db_value			Ptr to db_data_value for database
**					type/prec/length
**      ev_value                        Pointer to DB_DATA_VALUE for exported type
**
** Outputs:
**	adf_scb				Pointer to an ADF session control block.
**	    .adf_errcb			ADF_ERROR struct.  If an
**					error occurs the following fields will
**					be set.  NOTE: if .ad_ebuflen = 0 or
**					.ad_errmsgp = NULL, no error message
**					will be formatted.
**		.ad_errcode		ADF error code for the error.
**		.ad_errclass		Signifies the ADF error class.
**		.ad_usererr		If .ad_errclass is ADF_USER_ERROR,
**					this field is set to the corresponding
**					user error which will either map to
**					an ADF error code or a user-error code.
**		.ad_emsglen		The length, in bytes, of the resulting
**					formatted error message.
**		.adf_errmsgp		Pointer to the formatted error message.
**      *ev_value                       Filled appropriately.
**
**	Returns:
**	      The following DB_STATUS codes may be returned:
**	    E_DB_OK, E_DB_WARN, E_DB_ERROR, E_DB_SEVERE, E_DB_FATAL
**
**	      If a DB_STATUS code other than E_DB_OK is returned, the caller
**	    can look in the field adf_scb.adf_errcb.ad_errcode to determine
**	    the ADF error code.  The following is a list of possible ADF error
**	    codes that can be returned by this routine:
**
**          E_AD0000_OK                 Operation succeeded.
**          E_AD2004_BAD_DTID           Datatype id unknown to ADF.
**
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**      09-apr-93 (fred)
**          Created.
**      12-Jul-1993 (fred)
**          For the bit datatypes, since they are being output as
**          varchar, we need to increase the size of the
**          aforementioned varchar element by DB_CNTSIZE.  This is
**          necessary since the number of characters needed is given
**          by adu_bitsize, but we need space for the count.
[@history_template@]...
*/
DB_STATUS
adc_1dbtoev_ingres(
ADF_CB             *adf_scb,
DB_DATA_VALUE      *db_value,
DB_DATA_VALUE	   *ev_value)
{
    DB_DT_ID            bdt = abs(db_value->db_datatype);
    DB_DT_ID            bdtv;
    DB_STATUS		status = E_DB_OK;
    DB_DATA_VALUE       local_dv;
    i4                  must_coerce;

    must_coerce =
	Adf_globs->Adi_dtptrs[ADI_DT_MAP_MACRO(bdt)]->adi_dtstat_bits
	    & AD_NOEXPORT;

    bdtv = ADI_DT_MAP_MACRO(bdt);

    switch (bdt)
    {
    case DB_BYTE_TYPE:
	ev_value->db_length = db_value->db_length;
	ev_value->db_datatype = db_value->db_datatype;
	ev_value->db_prec = db_value->db_prec;
	ev_value->db_collID = db_value->db_collID;
	if (  (must_coerce)
	    ||(   ((adf_scb->adf_proto_level & AD_BYTE_PROTO) == 0)
	       && (Adf_globs->Adi_dtptrs[bdtv]->adi_dtstat_bits &
		                                    AD_CONDEXPORT)
	       )
	   )
	{
	    ev_value->db_datatype = DB_CHA_TYPE;
	}
	break;

    case DB_VBYTE_TYPE:
	STRUCT_ASSIGN_MACRO(*db_value, *ev_value);
	ev_value->db_length = db_value->db_length;
	ev_value->db_datatype = db_value->db_datatype;
	ev_value->db_prec = db_value->db_prec;
	ev_value->db_collID = db_value->db_collID;
	if (  (must_coerce)
	    ||(   ((adf_scb->adf_proto_level & AD_BYTE_PROTO) == 0)
	       && (Adf_globs->Adi_dtptrs[bdtv]->adi_dtstat_bits &
		                                    AD_CONDEXPORT)
	       )
	   )
	{
	    ev_value->db_datatype = DB_VCH_TYPE;
	}
	break;

    case DB_LBYTE_TYPE:
	ev_value->db_length = db_value->db_length;
	ev_value->db_datatype = db_value->db_datatype;
	ev_value->db_prec = db_value->db_prec;
	ev_value->db_collID = db_value->db_collID;
	if (  (must_coerce)
	    ||(   ((adf_scb->adf_proto_level & AD_BYTE_PROTO) == 0)
	       && (Adf_globs->Adi_dtptrs[bdtv]->adi_dtstat_bits &
		                                    AD_CONDEXPORT)
	       )
	   )
	{
	    ev_value->db_datatype = DB_LVCH_TYPE;
	}
	break;

    case DB_BIT_TYPE:
    case DB_VBIT_TYPE:
	ev_value->db_length = db_value->db_length;
	ev_value->db_datatype = db_value->db_datatype;
	ev_value->db_prec = db_value->db_prec;
	ev_value->db_collID = db_value->db_collID;
	if (  (must_coerce)
	    ||(   ((adf_scb->adf_proto_level & AD_BIT_PROTO) == 0)
	       && (Adf_globs->Adi_dtptrs[bdtv]->adi_dtstat_bits &
		                                    AD_CONDEXPORT)
	       )
	   )
	{
	    ev_value->db_datatype = DB_VCH_TYPE;
	    /* send them back as varchar, size appropriate to datatype */

	    local_dv.db_datatype = DB_INT_TYPE;
	    local_dv.db_length = sizeof(ev_value->db_length);
	    local_dv.db_prec = 0;
	    local_dv.db_data = (char *) &ev_value->db_length;
	    status = adu_bitsize(adf_scb, db_value, &local_dv);
	    ev_value->db_length += DB_CNTSIZE;
	}
	break;

    default:
	status = adu_error(adf_scb, E_AD9999_INTERNAL_ERROR, 0);
	break;
    }
    return(status);
}