Exemple #1
0
/* ProdExpr
 *  resolve a simple production by name
 *  create/return a VSimpleProd object
 */
rc_t VProdResolveSProduction ( const VProdResolve *self, VProduction **out, const SProduction *sprod )
{
    rc_t rc;
    VFormatdecl fd;

    /* check cache */
    VProduction *vprod = VCursorCacheGet ( self -> cache, & sprod -> cid );
    if ( vprod != NULL )
    {
        /* return valid or failed production */
        * out = vprod;
        return 0;
    }

    /* pre-fail */
    rc = VCursorCacheSet ( self -> cache, & sprod -> cid, FAILED_PRODUCTION );
    if ( rc == 0 )
    {
        /* resolve production type */
        if ( sprod -> trigger )
            memset ( & fd, 0, sizeof fd );
        else
        {
            rc = STypeExprResolveAsFormatdecl
                ( ( const STypeExpr* ) sprod -> fd, self -> schema, & fd );
        }
    }
    if ( rc == 0 )
    {
        /* resolve assignment expression */
        VTypedesc desc;
        rc = VProdResolveExpr ( self, out, & desc,
            & fd, sprod -> expr, false );
        if ( rc == 0 && * out != NULL )
        {
            const char *name = sprod -> name -> name . addr;
            assert ( name [ sprod -> name -> name . size ] == 0 );
            rc = VSimpleProdMake ( out, self -> owned, self -> curs, prodSimpleCast, 
                name, & fd, & desc, & sprod -> cid, * out, self -> chain );
            if ( rc == 0 )
            {
                void *ignore;
                rc = VCursorCacheSwap ( self -> cache, & sprod -> cid, * out, & ignore );
            }
        }
    }

    return rc;
}
Exemple #2
0
/* PhysExpr
 */
rc_t VProdResolveSPhysMember ( const VProdResolve *self,
    VProduction **out, const SPhysMember *smbr )
{
    rc_t rc;
    VCursor *curs;
    VPhysical *phys;

    curs = self -> curs;
    phys = VCursorCacheGet ( & curs -> phys, & smbr -> cid );
    if ( phys != NULL )
    {
        /* this guy should be readable, but it is not guaranteed */
        if ( phys != FAILED_PHYSICAL )
            * out = phys -> out;
        return 0;
    }

    /* pre-fail */
    rc = VCursorCacheSet ( & curs -> phys, & smbr -> cid, FAILED_PHYSICAL );
    if ( rc == 0 )
    {
        /* create physical object */
        rc = VPhysicalMake ( & phys, curs, smbr );
        if ( rc == 0 )
        {
            /* build physical */
            rc = VProdResolvePhysical ( self, phys );
            if ( rc == 0 && phys -> out > FAILED_PRODUCTION && phys -> b2p > FAILED_PRODUCTION )
            {
                /* set success */
                void *ignore;
                rc = VCursorCacheSwap ( & curs -> phys, & smbr -> cid, phys, & ignore );
                if ( rc == 0 )
                {
                    * out = phys -> out;
                    return 0;
                }
            }
            if ( GetRCState ( rc ) == rcUndefined )
                rc = 0;

            VPhysicalWhack ( phys, NULL );
        }
    }

    return rc;
}
Exemple #3
0
rc_t VProdResolveColumn ( const VProdResolve *self,
    VProduction **out, const SColumn *scol, bool alt )
{
    rc_t rc;
    VColumn *vcol;
    WColumn *wcol;
    VCursor *curs = self -> curs;

    /* decide upon behavior */
    if ( curs -> read_only )
    {
        if ( alt )
        {
            /* TODO: Generate warning message */
            return RC ( rcVDB, rcCursor, rcOpening, rcSchema, rcInvalid );
        }
        vcol = VCursorCacheGet ( & curs -> col, & scol -> cid );
        if ( vcol == NULL )
        {
            rc = VCursorMakeColumn ( curs, & vcol, scol );
            if ( rc != 0 )
                return rc;

#if OPEN_COLUMN_ALTERS_ROW
            rc = VectorAppend ( & curs -> row, & vcol -> ord, vcol );
            if ( rc != 0 )
            {
                VColumnWhack ( vcol, NULL );
                return rc;
            }
#endif
            rc = VCursorCacheSet ( & curs -> col, & scol -> cid, vcol );
            if ( rc != 0 )
            {
#if OPEN_COLUMN_ALTERS_ROW
                void *ignore;
                VectorSwap ( & curs -> row, vcol -> ord, NULL, & ignore );
                vcol -> ord = 0;
#endif
                VColumnWhack ( vcol, NULL );
                return rc;
            }
        }

        return VProdResolveColumnRead ( self, out, scol );
    }

    /* write cursor but read side */
    if ( self -> chain == chainDecoding )
    {
        if ( alt )
        {
            /* TODO: Generate warning message */
            return RC ( rcVDB, rcCursor, rcOpening, rcSchema, rcInvalid );
        }

        return VProdResolveColumnRead ( self, out, scol );
    }

    /* get existing column */
    wcol = VCursorCacheGet ( & curs -> col, & scol -> cid );
    if ( wcol == NULL )
    {
        /* normally write-only cursor must have existing column */
        if ( ! self -> discover_writable_columns )
            return 0;

        /* auto-create writable column for purposes of discovery */
        if ( scol -> read_only )
            return 0;
        rc = VCursorMakeColumn ( curs, & vcol, scol );
        if ( rc != 0 )
            return rc;

        /* add it to the row as if user had done it */
        rc = VectorAppend ( & curs -> row, & vcol -> ord, vcol );
        if ( rc == 0 )
        {
            /* add it to the indexed vector */
            rc = VCursorCacheSet ( & curs -> col, & scol -> cid, vcol );
            if ( rc != 0 )
            {
                void *ignore;
                VectorSwap ( & curs -> row, vcol -> ord, NULL, & ignore );
                vcol -> ord = 0;
            }
        }

        if ( rc != 0 )
        {
            VColumnWhack ( vcol, NULL );
            return rc;
        }

        wcol = ( WColumn* ) vcol;
    }

    /* create output production as required */
    if ( wcol -> out == NULL )
    {
        const char *name = scol -> name -> name . addr;
        rc = VColumnProdMake ( & wcol -> out, self -> owned,
            & wcol -> dad, prodColumnOut, name );
        if ( rc != 0 )
            return rc;
    }
    if ( alt )
    {
        * out = wcol -> dad . in;
        assert ( * out != NULL );
    }
    else
    {
        * out = wcol -> out;
    }
    return 0;
}