Beispiel #1
0
/*{
** 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));
}
Beispiel #2
0
/*{
** 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);
}
Beispiel #3
0
/*{
** 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);
}
Beispiel #4
0
/*{
** 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);
}
Beispiel #5
0
/*{
** 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 */
	}
    }
}