Contains strategy function

/*****************************************************************************
**
** Function name:
**
**      MyShapeContains
**
** Description:
**
**      Entrypoint for the SQL routine "Contains (MyShape,MyShape) returns
**      boolean".  This is an Rtree strategy function.
**
** Special Comments:
**
**      Because MyShape and its subtypes are variable length opaque 
**      datatypes, the UDT instances are passed in from the server 
**      wrapped in mi_lvarchars.
**
** Parameters:
**
**      mi_lvarchar *in1, *in2   UDT instances to be spatially compared.
**      MI_FPARAM   *fp          UDR function parameter & state info.
**
** Return value:
**
**      mi_boolean               True if shape2 is completely inside
**                               shape1.  If shape1 is a non-region
**                               subtype (e.g. a point), returns NULL.
**
*****************************************************************************/

UDREXPORT mi_boolean
MyShapeContains (mi_lvarchar *shape1,
                 mi_lvarchar *shape2,
                 MI_FPARAM   *fp)

{
    mi_boolean  bbox_overlap;
    mi_boolean  retval;
    MyShape *s1 = (MyShape *) mi_get_vardata (shape1);
    MyShape *s2 = (MyShape *) mi_get_vardata (shape2);

    SHAPE_TRACE_ENTER (MyShapeContains);

    CheckVersion (s1->hdr.version);
    CheckVersion (s2->hdr.version);

    /*
     * If shape1 is a non-region shape (e.g. point) it is not 
     * possible for shape1 to contain shape2 so return NULL.
     */
    switch (s1->hdr.tag)
    {
        case MyHeaderTag:
        case MyBoxTag:
        case MyCircleTag:
            break;

        case MyPointTag:
        default:
            mi_fp_setreturnisnull((fp), 0, MI_TRUE);
            retval = MI_FALSE;
            goto ContainsDone;
    }

    bbox_overlap = (s1->hdr.xmin <= s2->hdr.xmax &&
                    s2->hdr.xmin <= s1->hdr.xmax &&
                    s1->hdr.ymin <= s2->hdr.ymax &&
                    s2->hdr.ymin <= s1->hdr.ymax);

    /*
     * If bounding boxes do not overlap then it is not possible for
     * shape1 to contain shape2.
     */
    if (!bbox_overlap)
    {
        retval = MI_FALSE;
        goto ContainsDone;
    }

    /*
     * If bounding boxes overlap, and one or both objects are internal
     * index nodes, we cannot rule out the possibility that objects
     * in the subtree below this node satisfy the spatial test,
     * so return true.
     */
    if (s1->hdr.tag == MyHeaderTag || s2->hdr.tag == MyHeaderTag)
    {
        retval = MI_TRUE;
        goto ContainsDone;
    }

    /*
     * Both objects are actual shapes so perform an exact geometric test.
     * Note operand order is reversed so we can simply use the insideTable.
     */
    retval = Dispatch(insideTable, MI_FALSE, s2, s1);

ContainsDone:

    SHAPE_TRACE_EXIT (MyShapeContains);

    return retval;
}