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); }
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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }
/*{ ** 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)); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/*{ ** 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); }
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)); }
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); } }
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); }
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); }
/*{ ** 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); }
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); }
/*{ ** 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); }
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; }
/* ** { ** 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); }
/*{ ** 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); }
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); } }
/*{ ** 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); }