/*{ ** Name: opo_fordering - find or create multi-attribute ordering ** ** Description: {@comment_line@}... ** ** Inputs: [@PARAM_DESCR@]... ** ** Outputs: [@PARAM_DESCR@]... ** Returns: ** {@return_description@} ** Exceptions: ** [@description_or_none@] ** ** Side Effects: ** [@description_or_none@] ** ** History: [@history_template@]... */ OPO_ISORT opo_fordering( OPS_SUBQUERY *subquery, OPE_BMEQCLS *eqcmap) { OPO_ISORT ordering; /* number used to represent ** multi-attribute ordering */ OPO_SORT *orderp; /* ptr to multi-attribute ** ordering descriptor */ OPE_IEQCLS maxeqcls; maxeqcls = subquery->ops_eclass.ope_ev; ordering = BTnext( (i4)-1, (char *)eqcmap, (i4)maxeqcls); if (ordering < 0) return(OPE_NOEQCLS); if ( BTnext( (i4)ordering, (char *)eqcmap, (i4)maxeqcls) < 0) return(ordering); /* only one equivalence class ** so use it as the ordering */ if (!subquery->ops_msort.opo_base) opo_iobase(subquery); { /* search existing list for the multi-attribute ordering */ i4 maxorder; maxorder = subquery->ops_msort.opo_sv; for( ordering = 0; ordering < maxorder; ordering++) { orderp = subquery->ops_msort.opo_base->opo_stable[ordering]; if ( orderp->opo_stype == OPO_SINEXACT) { if (BTsubset((char *)eqcmap, (char *)orderp->opo_bmeqcls, (i4)maxeqcls) && BTsubset((char *)orderp->opo_bmeqcls, (char *)eqcmap, (i4)maxeqcls)) return((OPO_ISORT)(ordering+maxeqcls)); /* correct ordering found ** - FIXME need a bitwise ** equality */ } } } /* create new ordering since current one was not found */ ordering = opo_gnumber(subquery); /* get the next multi-attribute ** ordering number */ orderp = (OPO_SORT *)opn_memory(subquery->ops_global, (i4)sizeof(*orderp)); orderp->opo_stype = OPO_SINEXACT; orderp->opo_bmeqcls = (OPE_BMEQCLS *)opn_memory(subquery->ops_global, (i4)sizeof(OPE_BMEQCLS)); MEcopy((PTR)eqcmap, sizeof(OPE_BMEQCLS), (PTR)orderp->opo_bmeqcls); orderp->opo_eqlist = NULL; subquery->ops_msort.opo_base->opo_stable[ordering] = orderp; return((OPO_ISORT)(ordering+maxeqcls)); }
/*{ ** Name: oph_memory - get new histogram cell count array element ** ** Description: ** This routine is the "memory manager" for histogram cell count structures ** which will be replaced by the free space routines once they are ** integrated into the memory manager. ** ** If a free element is not available then this routine will allocate ** a new OPH_COUNT array. ** ** Inputs: ** subquery ptr to subquery being analyzed ** intervalp ptr to histogram component of an ** attribute describing characteristics ** of the histogram oph_fnct component ** ** Outputs: ** Returns: ** memory to OPH_COUNT cell count component of this histogram ** structure. ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-may-86 (seputis) ** initial creation ** 14-sep-93 (smc) ** Moved <cs.h> for CS_SID. ** 2-may-95 (wadag01) ** Removed unnecessary braces from the second block of code ** (caused error - 'return' : incompatible types on odt_us5). [@history_line@]... */ OPH_COUNTS oph_ccmemory( OPS_SUBQUERY *subquery, OPH_INTERVAL *intervalp) { i4 required; /* amount of memory to allocate */ OPH_COUNTS cellp; /* ptr to cell count array */ OPH_COERCE **coercepp; /* coercion use to traverse linked list*/ required = intervalp->oph_numcells * sizeof( OPN_PERCENT ) ; if (required < (i4)sizeof(OPH_COERCE)) required = sizeof(OPH_COERCE); /* fix for bug 63550 */ for (coercepp =(OPH_COERCE **)&subquery->ops_global->ops_estate.opn_ccfree; *coercepp; coercepp = &(*coercepp)->oph_next) { /* attempt to obtain memory from the free list */ if ((*coercepp)->oph_size == required) { /* correct size found so remove from list and return */ cellp = (OPH_COUNTS) *coercepp; *coercepp = (*coercepp)->oph_next; return(cellp); } } /* element does not exist on free list so allocate a new one */ cellp = (OPH_COUNTS) opn_memory( subquery->ops_global, (i4)required);/* ** allocate memory for cell count array */ return (cellp); }
/*{ ** Name: oph_memory - get new histogram element ** ** Description: ** This routine is the "memory manager" for histogram structures ** which will be replace by the free space routines once they are ** integrated into the memory manager. ** ** If a free element is not available then this routine will allocate ** a new histogram element ** ** Inputs: ** subquery ptr to subquery being analyzed ** ** Outputs: ** Returns: ** OPH_HISTOGRAM element ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-may-86 (seputis) ** initial creation ** 14-sep-93 (smc) ** Moved <cs.h> for CS_SID. [@history_line@]... */ OPH_HISTOGRAM * oph_memory( OPS_SUBQUERY *subquery) { OPH_HISTOGRAM **freehpp; /* ptr to ptr to next free element ** on the histogram free list */ OPH_HISTOGRAM *freehp; /* ptr to free histogram element */ if (*(freehpp = &subquery->ops_global->ops_estate.opn_hfree)) { /* an element exists in the free list of histograms so remove it */ freehp = *freehpp; /* save histogram element */ *freehpp = freehp->oph_next; /* remove it from the list */ } else { /* need to allocate a new histogram element */ freehp = (OPH_HISTOGRAM *) opn_memory( subquery->ops_global, (i4) sizeof(OPH_HISTOGRAM) ); /* allocate memory for histogram ** element */ } return (freehp); }
/*{ ** Name: opn_smemory - get new OPN_SUBTREE structure ** ** Description: ** This routine is the "memory manager" for OPN_SUBTREE structure, ** It will be replace by the free space routines once they are ** integrated into the memory manager. ** ** If a free element is not available then this routine will allocate ** a new OPN_SUBTREE element ** ** Inputs: ** subquery ptr to subquery being analyzed ** ** Outputs: ** Returns: ** ptr to OPN_SUBTREE element ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-may-86 (seputis) ** initial creation [@history_line@]... */ OPN_SUBTREE * opn_smemory( OPS_SUBQUERY *subquery) { OPN_SUBTREE *freest; /* ptr to free OPN_SUBTREE element*/ OPS_STATE *global; global = subquery->ops_global; if (freest = global->ops_estate.opn_stfree) { /* an element exists in the free list of OPN_SUBTREEs so remove it */ global->ops_estate.opn_stfree = (OPN_SUBTREE *)freest->opn_coforw; /* remove it from the ** list */ } else { /* need to allocate a new OPN_SUBTREE element */ if (global->ops_mstate.ops_mlimit > (i4)global->ops_mstate.ops_memleft) { /* check if memory limit has been reached prior to allocating ** another RLS node from the stream */ opn_fmemory(subquery, (PTR *)&global->ops_estate.opn_stfree); /* ** attempt to free unused subtree ** structures */ if (freest = global->ops_estate.opn_stfree) { /* check if garbage collection has found any free nodes */ global->ops_estate.opn_stfree = (OPN_SUBTREE *)freest->opn_coforw; /* deallocate from ** free list */ } } if (!freest) freest = (OPN_SUBTREE *) opn_memory( subquery->ops_global, (i4) sizeof(OPN_SUBTREE) ); /* allocate memory for OPN_SUBTREE ** element */ } return (freest); }
/*{ ** Name: opn_recover - recover from an out-of-memory error ** ** Description: ** This routine will copy the best CO tree to non-enumeration memory ** and reinitialize the enumeration memory stream, and related ** variables. The purpose of this is to allow enumeration to continue ** from this point in the search space. ** ** Inputs: ** subquery ptr to subquery being analyzed ** ** Outputs: ** Returns: ** VOID ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 31-oct-86 (seputis) ** initial creation ** 14-aug-89 (seputis) ** - fix b6538, initialize opn_sfree ** 16-jul-91 (seputis) ** - fix access violation in star tests ** - check for array of query plans to copy out of enumeration ** memory for function aggregates. ** 18-sep-02 (inkdo01) ** Changes to copy out logic for new enumeration (only copy out ** bottom left CO fragment). ** 18-oct-02 (inkdo01) ** Externalized for accessibility from opn_newenum. ** 29-oct-04 (inkdo01) ** Added parm to opo_copyfragco(). ** 5-oct-2007 (dougi) ** Count opn_recover() calls. */ VOID opn_recover( OPS_SUBQUERY *subquery) { OPS_STATE *global; /* ptr to global state variable */ global = subquery->ops_global; global->ops_mstate.ops_recover++; /* Check for new enumeration & just copy fragment. */ if (subquery->ops_mask & OPS_LAENUM && subquery->ops_bestfragco && !subquery->ops_fraginperm && !subquery->ops_lastlaloop) { opo_copyfragco(subquery, &subquery->ops_bestfragco, TRUE); subquery->ops_fraginperm = TRUE; } /* Otherwise, treat old enumeration. We also need logic to ** copy out bestco when new enumeration is on the last loop. ** bestco is really the final plan at that point. */ if (subquery->ops_bestco || ( (global->ops_cb->ops_smask & OPS_MDISTRIBUTED) && subquery->ops_dist.opd_bestco )) opo_copyco(subquery, &subquery->ops_bestco, FALSE);/* copy the ** best CO prior to deallocating ** memory - FALSE indicates that ** this may not be the final CO ** tree */ opu_deallocate(global, &global->ops_estate.opn_streamid); global->ops_estate.opn_streamid = opu_allocate(global); subquery->ops_msort.opo_base = NULL; /* all this info was allocated ** out of enumeration memory */ /* initialize all memory management free lists */ global->ops_estate.opn_sfree = NULL; /* init the OPN_SDESC free list */ global->ops_estate.opn_rlsfree = NULL; /* init the RLS free list */ global->ops_estate.opn_eqsfree = NULL; /* init the EQS free list */ global->ops_estate.opn_stfree = NULL; /* init the SUBTREE free list */ global->ops_estate.opn_cofree = NULL; /* init the CO free list */ global->ops_estate.opn_hfree = NULL; /* init the HISTOGRAM free list */ global->ops_estate.opn_ccfree = NULL; /* init the cell count free list */ if (global->ops_cb->ops_smask & OPS_MDISTRIBUTED) opd_recover(global); /* reinitialize the distributed ** memory structures which will be ** lost when the memory stream is ** recovered */ global->ops_estate.opn_sbase = (OPN_ST *) opn_memory( global, (i4) sizeof( OPN_ST )); /* get memory for savework */ MEfill( sizeof(OPN_ST), (u_char)0, (PTR)global->ops_estate.opn_sbase->opn_savework); /* ** init all ptrs to NULL */ global->ops_estate.opn_slowflg = TRUE; /* have any intermediate results ** been deleted? */ { /* initialize joinop range table references to enumeration memory */ OPV_RT *vbase; /* ptr to local joinop range table */ OPV_IVARS varno; /* joinop range var number of ** element being reset */ vbase = subquery->ops_vars.opv_base;/* base of local joinop range table */ for (varno = subquery->ops_vars.opv_rv; varno-- > 0;) { vbase->opv_rt[varno]->opv_trl->opn_eqp = 0; /* reset ptrs into ** enumeration memory */ } } }