/*{ ** Name: opz_addatts - add joinop attributes to the array ** ** Description: ** This routine will add or find the appropriate joinop attribute ** to the joinop attributes array given the ** (range variable, range variable attribute number) pair. ** ** The exception to this rule occurs with function attributes which ** always results in a new joinop attribute being allocated. A ** function attribute uses "OPZ_FANUM" as the input attribute number. ** ** Inputs: ** subquery ptr to subquery being analyzed ** joinopvar index into joinop range table ** dmfattr dmf attribute number ** datatype ptr to ADT datatype ** ** Outputs: ** Returns: ** joinop attribute number ** Exceptions: ** none ** ** Side Effects: ** An entry may be allocated in the joinop attributes array ** (OPS_SUBQUERY->ops_attrs) ** ** History: ** 20-apr-86 (seputis) ** initial creation addatts ** 06-nov-89 (fred) ** Added support for non-histogrammable datatypes. This support ** entails providing a simple, coordinated replacement for this ** histogram. In our case, the datatype & length will be varchar, ** minimum & maximum being those for varchar, and adc_helem() ** replacement will be the histogram for "nohistos". ** ** This code is done in OPF as opposed to ADF because I think it ** desirable that OPF manage the histogram replacement. ADF will not ** know the appropriate values. Furthermore, it is more desirable to ** teach OPF to manage w/out histograms; however, that change is ** beyond the scope of this project. ** 26-dec-90 (seputis) ** init mask of booleans associated with attribute descriptor ** 18-jan-93 (rganski) ** Character Histogram Enhancements project: ** Initialize attr_ptr->opz_histogram.oph_dataval.db_length to 8 ** before call to adc_hg_dtln(), which has been changed; this gives ** old behavior (limit for char types was 8). This length may be ** changed later when RDF gets info from iistatistics. ** 24-may-93 (rganski) ** Character Histograms Enhancements project: ** Initialize attr_ptr->opz_histogram.oph_dataval.db_length to 0 ** before call to adc_hg_dtln(), which causes histogram value to be ** same length as attribute. This is necessary because otherwise the ** histogram value, which is used to determine selectivity of boolean ** factors, is truncated; this removes the benefits of having long ** histogram values. The histogram value length is adjusted in ** oph_catalog(), which reads the actual length from iistatistics (or ** truncates to 8, for old histograms). ** 6-dec-93 (ed) ** - bug 56139 - project union view before it is instantiated ** 09-oct-98 (matbe01) ** Added NO_OPTIM for NCR to eliminate runtime error that produces the ** message: E_OP0889 Eqc is not available at a CO node. ** 6-sep-04 (hayke02) ** Add OPZ_COLLATT attribute if OPS_COLLATION is on (resdom list, ** collation sequence). This change fixes problem INGSRV 2940, bug ** 112873. ** 8-nov-05 (hayke02) ** Add OPZ_VAREQVAR if OPS_VAREQVAR is on. Return if OPZ_VAREQVAR is ** not set and the attribute is found. This ensures that the fix for ** 110675 is limited to OPZ_VAREQVAR PST_BOP nodes. This change ** fixes bug 115420 problem INGSRV 3465. ** 15-aug-2007 (huazh01) ** ensure the datatype/length info of a created attribute matches ** the corresponding column type/length info on the user table. ** bug 117316. ** [@history_line@]... */ OPZ_IATTS opz_addatts( OPS_SUBQUERY *subquery, OPV_IVARS joinopvar, OPZ_DMFATTR dmfattr, DB_DATA_VALUE *datatype) { OPZ_IATTS attribute; /* used to save joinop attribute ** number if found by opz_findatt */ RDR_INFO *rel; /* FIXME - need to deal with unsigned compare problem here */ if ( (dmfattr != OPZ_FANUM) && (dmfattr != OPZ_SNUM) && (dmfattr != OPZ_CORRELATED) && (attribute = opz_findatt(subquery, joinopvar, dmfattr)) >= 0 && !(subquery->ops_attrs.opz_base->opz_attnums[attribute]->opz_mask & OPZ_VAREQVAR && subquery->ops_mask2 & OPS_COLLATION && (abs(datatype->db_datatype) == DB_CHA_TYPE || abs(datatype->db_datatype) == DB_VCH_TYPE || abs(datatype->db_datatype) == DB_CHR_TYPE || abs(datatype->db_datatype) == DB_TXT_TYPE)) ) return( attribute ); /* if this (joinopvar,dmfattr) pair ** exists and is not a function ** attribute, or subselect attribute ** then return */ { /* create new joinop attribute */ OPZ_IATTS nextattr; /* next available joinop attribute ** number */ OPS_STATE *global; /* ptr to global state variable */ global = subquery->ops_global; /* get ptr to global state variable */ if ( (nextattr = subquery->ops_attrs.opz_av++) >= OPZ_MAXATT) opx_error(E_OP0300_ATTRIBUTE_OVERFLOW); /* exit with error ** if no more room in attributes ** array */ { OPZ_ATTS *attr_ptr; /* ptr to newly created joinop ** attribute element */ OPV_VARS *var_ptr; /* ptr to respective joinop ** variable containing attribute */ var_ptr = subquery->ops_vars.opv_base->opv_rt[joinopvar]; /* allocate new joinop attribute structure and initialize */ subquery->ops_attrs.opz_base->opz_attnums[nextattr] = attr_ptr = (OPZ_ATTS *) opu_memory( global, (i4) sizeof(OPZ_ATTS)); MEfill(sizeof(*attr_ptr), (u_char)0, (PTR)attr_ptr); /* b117316: ** ** the fix to b109879 set PST_VAR node under the RESDOM to ** to nullable and increase the db_length by one, though ** the column corresponds to PST_VAR is defined as not null. ** Need to reset them to not null in order to prevent ** wrong db_type and db_length being used during query ** execution. e.g., wrong db_type and db_length could cause OPC ** to generate a set of ADF code which materialize tuples ** using incorrect offset and cause wrong result. ** */ rel = var_ptr->opv_grv->opv_relation; if (datatype->db_datatype < 0 && dmfattr > 0 && rel && rel->rdr_attr[dmfattr]->att_type * -1 == datatype->db_datatype && rel->rdr_attr[dmfattr]->att_width + 1 == datatype->db_length) { datatype->db_datatype = rel->rdr_attr[dmfattr]->att_type; datatype->db_length = rel->rdr_attr[dmfattr]->att_width; } attr_ptr->opz_varnm = joinopvar; /* index into local range table */ BTset( (i4)nextattr, (char *)&var_ptr->opv_attrmap); /* indicate ** that this joinop ** attribute belongs to this range ** variable */ attr_ptr->opz_gvar = var_ptr->opv_gvar; /* move global range ** variable number to attribute */ attr_ptr->opz_attnm.db_att_id = dmfattr;/* dmf attribute of ** range variable */ STRUCT_ASSIGN_MACRO((* datatype), attr_ptr->opz_dataval); attr_ptr->opz_equcls = OPE_NOEQCLS; /* this attribute has not been ** assigned an equivalence class yet */ attr_ptr->opz_func_att = OPZ_NOFUNCATT; /* this indicates that a ** function attribute is not ** associated with this joinop ** attribute element */ if ((dmfattr != OPZ_FANUM) && (dmfattr != OPZ_SNUM) && (dmfattr != OPZ_CORRELATED) && (attribute >= 0)) attr_ptr->opz_mask |= OPZ_COLLATT; if (subquery->ops_mask2 & OPS_VAREQVAR) attr_ptr->opz_mask |= OPZ_VAREQVAR; if ((var_ptr->opv_grv->opv_gmask & OPV_UVPROJECT) && (dmfattr >= 0)) { /* if union view exists in which a projection is possible ** (i.e. a UNION ALL view) then ** mark the attribute which are referenced in the union view*/ BTset((i4)dmfattr, (char *)var_ptr->opv_grv->opv_attrmap); } { /* initialize the histogram information associated with this ** attribute */ DB_STATUS hgstatus; /* ADT return status */ i4 dt_bits; hgstatus = adi_dtinfo(global->ops_adfcb, datatype->db_datatype, &dt_bits); if ((hgstatus == E_AD0000_OK) && (dt_bits & AD_NOHISTOGRAM)) { attr_ptr->opz_histogram.oph_dataval.db_datatype = OPH_NH_TYPE; attr_ptr->opz_histogram.oph_dataval.db_prec = OPH_NH_PREC; attr_ptr->opz_histogram.oph_dataval.db_length = OPH_NH_LENGTH; } else { attr_ptr->opz_histogram.oph_dataval.db_length = 0; hgstatus = adc_hg_dtln(global->ops_adfcb, datatype, &attr_ptr->opz_histogram.oph_dataval ); } # ifdef E_OP0780_ADF_HISTOGRAM if ((hgstatus != E_AD0000_OK) || (attr_ptr->opz_histogram.oph_dataval.db_datatype < 0) /* do not expect a nullable ** histogram datatype */ ) opx_verror( hgstatus, E_OP0780_ADF_HISTOGRAM, global->ops_adfcb->adf_errcb.ad_errcode); /* ** abort if unexpected error occurs */ # endif attr_ptr->opz_histogram.oph_dataval.db_data = NULL; /* init the ** data value ptr */ attr_ptr->opz_histogram.oph_numcells = OPH_NOCELLS; /* histogram ** has not been fetched so no cells ** exist at this point */ attr_ptr->opz_histogram.oph_histmm = NULL; /* no histogram ** exists at this point */ attr_ptr->opz_histogram.oph_mindomain = NULL; /* no minimum ** value for this histogram yet */ attr_ptr->opz_histogram.oph_maxdomain = NULL; /* no maximum ** value for this histogram yet */ } if (dmfattr == DB_IMTID) { /* implicit TID found so an equivalence class needs to be ** created ... so we know the equivalence class of the ** implicit TID for this (since the implicit TID is referenced ** by an index or explicitly in the qualification) */ var_ptr->opv_primary.opv_tid = ope_neweqcls( subquery, nextattr ); } } return( nextattr ); /* return joinop attribute which has ** been assigned */ } }
/* ** Name: pst_rsdm_dt_resolve - determine type, length, precision to be stored ** in RESDOM node based on those found in its ** right child ** ** Description: ** If the right child of RESDOM exists, copy the child's type, length, and ** precision into the descriptor for the RESDOM node; if adi_dtinfo() ** indicates that this type cannot be sent to FE, call adc_dbtoev() to ** obtain an translate it into an "exportable" data type. ** If the right child does not exist, then simply set type to DB_NODT and ** length and precision to 0. ** ** Input: ** right right child of the RESDOM node; NULL if none exists ** cb PSF session CB ** pss_qualdepth if set to 1, the resdom represents an element of a ** target list which will be returned to FE ** psq_cb PSF request CB ** psq_mode mode of the query ** ** Output: ** coldesc type/length,precision descriptor will be filled in ** att_type data type ** att_width length ** att_prec precision ** ** Side effects: ** none ** ** Returns: ** E_DB_{OK,ERROR} ** ** History: ** ** 08-jan-92 (andre) ** broke off from the body of pst_adresdom() to enable psl_p_tlist() to ** correctly process UDTs found in the target list ** 06-oct-92 (andre) ** we should not call adc_dbtoev() when processing INSERT ... SELECT. ** this can be determined by checking if ** (!cb->pss_resrng || !cb->pss_resrng->pss_used || ** cb->pss_resrng->pss_rgno < 0) ** 21-jun-93 (robf) ** we should be doing adc_dbtoev in QUEL retrieve (x.all), where ** pss_qualdepth is 0, so changed ** && (cb->pss_qualdepth ==1) ** to ** && (cb->pss_qualdepth <=1) ** 15-apr-05 (inkdo01) ** Add collation ID support. ** 29-Oct-2007 (hanal04) Bug 119368 ** If the front end does not have GCA i8 support then cast the ** RESDOMs as i4s. ** 26-Nov-2009 (hanal04) Bug 122938 ** If the front end does not support the maximum precision ** for decimals downgrade/convert to the supported maximum ** precision level. ** 7-Dec-2009 (hanal04) Bug 123019, 122938 ** Adjust previous change for Bug 122938. Scale only needs to be ** adjusted if it is greater than the new precision. This prevents ** negative scale values seen in replicator testing. ** 25-Feb-2010 (hanal04) Bug 123291 ** Remove downgrade of decimal RESDOMs, old clients can display ** precision in excess of 31, they just can't use them in ascii ** copy. ** 22-Mar-2010 (toumi01) SIR 122403 ** Init new encryption variables. */ DB_STATUS pst_rsdm_dt_resolve( PST_QNODE *right, DMT_ATT_ENTRY *coldesc, PSS_SESBLK *cb, PSQ_CB *psq_cb) { DB_STATUS status; ADF_CB *adf_scb; i2 null_adjust = 0; if (right != (PST_QNODE *) NULL) { coldesc->att_type = right->pst_sym.pst_dataval.db_datatype; coldesc->att_width = right->pst_sym.pst_dataval.db_length; coldesc->att_prec = right->pst_sym.pst_dataval.db_prec; coldesc->att_collID = right->pst_sym.pst_dataval.db_collID; /* ** Internally some nodes have their type resolved later (ie, aggs) ** and may enter here with DB_NODT as the type. To avoid errors ** from adi_dtinfo, we do not call if the type is DB_NODT. */ if (coldesc->att_type != DB_NODT) { i4 dt_status; ADF_CB *adf_scb; adf_scb = (ADF_CB *) cb->pss_adfcb; status = adi_dtinfo(adf_scb, coldesc->att_type, &dt_status); if (DB_FAILURE_MACRO(status)) { adf_scb->adf_errcb.ad_errclass = ADF_USER_ERROR; psf_adf_error(&adf_scb->adf_errcb, &psq_cb->psq_error, cb); return(status); } if ( (dt_status & (AD_NOEXPORT | AD_CONDEXPORT)) && ((psq_cb->psq_mode == PSQ_RETRIEVE) || (psq_cb->psq_mode == PSQ_DEFCURS)) && (cb->pss_qualdepth <=1) /* make sure we are not processing INSERT ... SELECT */ && ( !cb->pss_resrng || !cb->pss_resrng->pss_used || cb->pss_resrng->pss_rgno < 0 ) ) { DB_DATA_VALUE db_value; DB_DATA_VALUE ev_value; db_value.db_datatype = coldesc->att_type; db_value.db_length = coldesc->att_width; db_value.db_prec = coldesc->att_prec; db_value.db_collID = coldesc->att_collID; status = adc_dbtoev(adf_scb, &db_value, &ev_value); if (DB_FAILURE_MACRO(status)) { adf_scb->adf_errcb.ad_errclass = ADF_USER_ERROR; psf_adf_error(&adf_scb->adf_errcb, &psq_cb->psq_error, cb); return(status); } coldesc->att_type = ev_value.db_datatype; coldesc->att_width = ev_value.db_length; coldesc->att_prec = ev_value.db_prec; coldesc->att_collID = ev_value.db_collID; } } /* If valid data type */ /* If client can not handle i8 INTs downgrade to i4 */ if ( abs(coldesc->att_type) == DB_INT_TYPE) { adf_scb = (ADF_CB *) cb->pss_adfcb; if ( !(adf_scb->adf_proto_level & AD_I8_PROTO)) { if(coldesc->att_type < 0) { null_adjust = 1; } if((coldesc->att_width - null_adjust) == sizeof(i8)) { coldesc->att_width -= sizeof(i4); } } } } else { coldesc->att_type = (DB_DT_ID) DB_NODT; coldesc->att_width = (i4) 0; coldesc->att_prec = (i4) 0; coldesc->att_collID = (i4) -1; coldesc->att_geomtype = (i2) -1; coldesc->att_srid = (i4) -1; coldesc->att_encflags = (i2) 0; coldesc->att_encwid = 0; } 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 dm1ch_compress( DMP_ROWACCESS *rac, char *rec, i4 rec_size, char *crec, i4 *crec_size) { u_char *pIn; u_char *pOut; i4 iInSize; i4 iOutSize; BIT_FILE BitFile; i2 Character; u_i2 StringCode; u_i2 index; i4 rc; DICTCONTROL DictCtrl; DICTIONARY Dict[TABLE_SIZE]; i4 i; i2 att_ln, str_ln; i2 type; i2 abs_type; i4 dt_bits; DB_ATTS *att; DB_ATTS **attpp; ADF_CB adf_scb; MEfill(sizeof(ADF_CB),0,(PTR)&adf_scb); adf_scb.adf_maxstring = DB_MAXSTRING; /* preen the input record of garbage */ pIn = (u_char *)rec; attpp = rac->att_ptrs; i = rac->att_count; while (--i >= 0) { att = *attpp++; att_ln = att->length; type = att->type; if (att->ver_dropped > att->ver_added) continue; /* ** Obtain info about the data type. ** It's used to check for coupons then later for variable len */ abs_type = (type < 0) ? -type: type; adi_dtinfo(&adf_scb, abs_type, &dt_bits); if ((type < 0) && !(dt_bits & AD_PERIPHERAL)) { /* nullable */ if (pIn[--att_ln] & ADF_NVL_BIT) { /* it is null so zap the value */ MEfill(att_ln, 0x00, pIn); pIn += att->length; continue; } type = (-type); } /* ** either not a nullable datatype or ** nullable but not null right now */ switch (type) { /* ** currently only interested in variable length ** attributes ; it is these which potentially have ** garbage past their end - all others are either complete ** or blank padded already */ case DB_VCH_TYPE: case DB_TXT_TYPE: case DB_VBYTE_TYPE: /* get length and adjust */ I2ASSIGN_MACRO(((DB_TEXT_STRING *)pIn)->db_t_count, str_ln); str_ln += DB_CNTSIZE; if (str_ln < att_ln) MEfill((att_ln - str_ln), 0x00, (pIn + str_ln)); break; case DB_NVCHR_TYPE: /* get length and adjust */ I2ASSIGN_MACRO(((DB_TEXT_STRING *)pIn)->db_t_count, str_ln); str_ln = str_ln * sizeof(UCS2) + DB_CNTSIZE; if (str_ln < att_ln) MEfill((att_ln - str_ln), 0x00, (pIn + str_ln)); break; default: break; } /* point to next attribute */ pIn += att->length; } /* now compress the preened record */ pIn = (u_char*)rec; pOut = (u_char*)crec; iInSize = rec_size; /* write compression indicator */ *pOut++ = (char)TRUE; dm1ch_InitDictionary(&Dict[0], &DictCtrl); BitFile.pDataPtr = pOut; BitFile.cbDataLen = (u_i2)(rec_size); BitFile.cResidual = 0; BitFile.Residual = 0L; StringCode = pIn[0]; pIn++; iInSize--; while (iInSize > 0) { Character = pIn[0]; pIn++; iInSize--; index = dm1ch_FindChildNode(&Dict[0], StringCode, Character); if (Dict[index].CodeValue != UNUSED) { StringCode = Dict[index].CodeValue; } else { Dict[index].CodeValue = DictCtrl.NextCode++; Dict[index].ParentCode = StringCode; Dict[index].Character = (char) Character; rc = dm1ch_OutputBits(&BitFile, (u_i4) StringCode, DictCtrl.CurrentCodeBits); if (rc == -1) break; /* Compression didn't compress */ StringCode = Character; if (DictCtrl.NextCode > (u_i2) MAX_CODE) { rc = dm1ch_OutputBits(&BitFile, (u_i4) FLUSH_CODE, DictCtrl.CurrentCodeBits); if (rc == -1) break; /* Compression didn't compress */ dm1ch_InitDictionary(&Dict[0], &DictCtrl); } /* Dictionary has filled up */ else if (DictCtrl.NextCode > DictCtrl.NextBumpCode) { rc = dm1ch_OutputBits(&BitFile, (u_i4) BUMP_CODE, DictCtrl.CurrentCodeBits); if (rc == -1) break; /* Compression didn't compress */ DictCtrl.CurrentCodeBits++; DictCtrl.NextBumpCode <<= 1; DictCtrl.NextBumpCode |= 1; } /* Increase the number of code bits */ } } if (rc == 0) rc = dm1ch_OutputBits(&BitFile, (u_i4) StringCode, DictCtrl.CurrentCodeBits); if (rc == 0) rc = dm1ch_OutputBits(&BitFile, (u_i4) END_OF_STREAM, DictCtrl.CurrentCodeBits); if (rc == 0) rc = dm1ch_CloseBitFile(&BitFile); if (rc == 0) { iOutSize = rec_size - BitFile.cbDataLen + 1; } else /* compression failed to reduce the size, so use original */ { /* write compression indicator */ pOut = (u_char*)crec; *pOut++ = (char)FALSE; /* write original data */ MEcopy(rec, rec_size, pOut); iOutSize = rec_size + 1; } *crec_size = iOutSize; /* Return the size of compressed data */ return(E_DB_OK); } /* dm1ch_compress */