/*{ ** Name: PSQ_TCNVT - convert db_data_value to text form ** ** Description: ** This routine takes any user supplied db_data_value and converts ** it to the value's textual representation. This is required for the ** iiqrytext catalog. It is assumed that all datavalues can be written ** into a character representation. ** ** Inputs: ** sess_cb session control block ** .pss_adfcb adf session control block for output ** arguments. ** header Pointer to chain header ** dbval db_data_value ** result Place to put pointer to new piece ** err_blk Filled in if an error happens ** ** Outputs: ** result Filled in with pointer to chain element ** err_blk Filled in if an error happens ** Returns: ** E_DB_OK Success ** E_DB_ERROR Non-catastrophic failure ** E_DB_FATAL Catastrophic failure ** Exceptions: ** none ** ** Side Effects: ** Allocates memory ** ** History: ** 29-jun-87 (daved) ** written ** 28-jan-91 (andre) ** fix bug 35446: size of a new piece should include quotes, if they ** were added. ** 18-nov-91 (rog) ** Fixed bug 40869, et alia: the above fix missed adding the quotes ** to the total size and not just the piece size. ** 23-Sep-2009 (kiria01) b122578 ** Initialise the ADF_FN_BLK .adf_fi_desc and adf_dv_n members. ** 19-Aug-2010 (kschendel) b124282 ** Make sure fi-desc is always set to something. */ DB_STATUS psq_tcnvt( PSS_SESBLK *sess_cb, PTR header, DB_DATA_VALUE *dbval, PTR *result, DB_ERROR *err_blk) { PSQ_THEAD *hp; PSQ_TEXT *tp; i4 err_code; DB_STATUS status; ADF_CB *adf_cb; ADF_FN_BLK adffn; i4 dv_size; i4 count; char *cptr; char *quote_char; DB_TEXT_STRING *string; ADI_DT_NAME dt_fname; ADI_DT_NAME dt_tname; char f4_style; char f8_style; i4 f4_width; i4 f8_width; i4 f4_prec; i4 f8_prec; i4 totype; i4 is_string; hp = (PSQ_THEAD *) header; adf_cb = (ADF_CB *) sess_cb->pss_adfcb; status = E_DB_OK; totype = (DB_DT_ID) DB_LTXT_TYPE; adffn.adf_r_dv.db_datatype = totype; if (dbval->db_datatype == totype) dv_size = dbval->db_length; else dv_size = 0; /* JRBCMT -- PSF is not allowed to know this!! First of all, date is */ /* missing from the list below and decimal will soon need to be on it. */ /* But also, we need to fix this code so that it doesn't make */ /* assumptions about what types exist. I think the proper approach is */ /* to quote all non-intrinsic types, but this should be investigated. */ /* are we dealing with a string type (incoming). */ if (abs(dbval->db_datatype) == DB_INT_TYPE || abs(dbval->db_datatype) == DB_FLT_TYPE || abs(dbval->db_datatype) == DB_MNY_TYPE || abs(dbval->db_datatype) == DB_BOO_TYPE) { is_string = FALSE; quote_char = (char *) NULL; } else { is_string = TRUE; quote_char = (sess_cb->pss_lang == DB_SQL) ? "\'" : "\""; } /* set the floating point conversion display */ f4_style = adf_cb->adf_outarg.ad_f4style; f8_style = adf_cb->adf_outarg.ad_f8style; f4_width = adf_cb->adf_outarg.ad_f4width; f8_width = adf_cb->adf_outarg.ad_f8width; f4_prec = adf_cb->adf_outarg.ad_f4prec; f8_prec = adf_cb->adf_outarg.ad_f8prec; adf_cb->adf_outarg.ad_f4style = 'n'; adf_cb->adf_outarg.ad_f8style = 'n'; adf_cb->adf_outarg.ad_f4width = 20; adf_cb->adf_outarg.ad_f8width = 20; adf_cb->adf_outarg.ad_f4prec = 10; adf_cb->adf_outarg.ad_f8prec = 10; /* get the function instance id for this conversion */ status = adi_ficoerce(adf_cb, dbval->db_datatype, totype, &adffn.adf_fi_id); if (status != E_DB_OK) { goto exit; } /* determine the result size. */ status = adi_fidesc(adf_cb, adffn.adf_fi_id, &adffn.adf_fi_desc); if (status != E_DB_OK) { goto exit; } if (!dv_size) { /* Now lets fill in the datatype length info and allocate space for the ** data. */ status = adi_0calclen(adf_cb, &adffn.adf_fi_desc->adi_lenspec, 1, &dbval, &adffn.adf_r_dv); dv_size = adffn.adf_r_dv.db_length; if (status != E_DB_OK) { goto exit; } } /* if string, add room for quotes */ if (is_string) dv_size += 2 * CMbytecnt(quote_char); /* Allocate enough space for PSQ_TEXT structure containing piece */ hp->psq_tmem.ulm_psize = dv_size + sizeof(PSQ_TEXT) - 1; status = ulm_palloc(&hp->psq_tmem); if (status != E_DB_OK) { if (hp->psq_tmem.ulm_error.err_code == E_UL0005_NOMEM) { psf_error(E_PS0F02_MEMORY_FULL, 0L, PSF_CALLERR, &err_code, err_blk, 0); } else (VOID) psf_error(E_PS0371_ALLOC_TEXT_CHAIN, hp->psq_tmem.ulm_error.err_code, PSF_INTERR, &err_code, err_blk, 0); return (status); } *result = hp->psq_tmem.ulm_pptr; tp = (PSQ_TEXT*) *result; string = (DB_TEXT_STRING*) tp->psq_tval; /* Fill in text piece */ adffn.adf_r_dv.db_length = dv_size; adffn.adf_r_dv.db_data = (PTR) string; adffn.adf_dv_n = 1; STRUCT_ASSIGN_MACRO(*dbval, adffn.adf_1_dv); adffn.adf_pat_flags = AD_PAT_DOESNT_APPLY; if ((status = adf_func(adf_cb, &adffn)) != E_DB_OK) { goto exit; } /* CAUTION: entering tricky code. ** string is a variable containing a text datatype. We want to convert ** to a C datatype. We also want to add quote characters if the datatype ** was a string type. We grab the count from the string variable first. ** we can then use the 2 byte count for character data. */ count = string->db_t_count; cptr = (char *) string; if (is_string) { /* ** for strings, copy the opening quote (" or ', depending on language) */ CMcpychar(quote_char, cptr); cptr += CMbytecnt(quote_char); } MEcopy((PTR) string->db_t_text, count, (PTR) cptr); cptr += count; if (is_string) { /* ** for strings, copy the closing quote (" or ', depending on language) */ CMcpychar(quote_char, cptr); } /* if storing a string, do not forget to account for quotes (bug 35446) */ tp->psq_psize = (is_string) ? count + 2 * CMbytecnt(quote_char) : count; /* Hook it up to the chain */ tp->psq_next = (PSQ_TEXT *) NULL; if (hp->psq_last != (PSQ_TEXT *) NULL) { hp->psq_last->psq_next = tp; tp->psq_prev = hp->psq_last; } else { tp->psq_prev = NULL; } hp->psq_last = tp; if (hp->psq_first == (PSQ_TEXT *) NULL) hp->psq_first = tp; /* Add in the length to the total for the chain */ hp->psq_tsize += tp->psq_psize; exit: /* set the floating point conversion display */ adf_cb->adf_outarg.ad_f4style = f4_style; adf_cb->adf_outarg.ad_f8style = f8_style; adf_cb->adf_outarg.ad_f4width = f4_width; adf_cb->adf_outarg.ad_f8width = f8_width; adf_cb->adf_outarg.ad_f4prec = f4_prec; adf_cb->adf_outarg.ad_f8prec = f8_prec; if (status != E_DB_OK) { (VOID) adi_tyname(adf_cb, dbval->db_datatype, &dt_fname); (VOID) adi_tyname(adf_cb, totype, &dt_tname); (VOID) psf_error(2911L, 0L, PSF_USERERR, &err_code, err_blk, 3, sizeof (sess_cb->pss_lineno), &sess_cb->pss_lineno, psf_trmwhite(sizeof(dt_fname), (char *) &dt_fname), &dt_fname, psf_trmwhite(sizeof (dt_tname), (char *) &dt_tname), &dt_tname); return (E_DB_ERROR); } return (status); }
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); }