Пример #1
0
/* ResolvePhysical
 *  resolves a physical column
 */
static
rc_t VProdResolvePhysicalWrite ( const VProdResolve *self, VPhysical *phys )
{
    VTypedesc desc;
    VFormatdecl fd;
    VProdResolve pr;
    VProduction *prod;
    VCursor *curs = self -> curs;

    const char *name;
    const SExpression *enc;
    const SPhysMember *smbr;

    /* open the physical column for write
       load column metadata/schema, complete
       physical member description. */
    rc_t rc = VPhysicalOpenWrite ( phys,
        ( VSchema* ) self -> schema, curs -> tbl );
    if ( rc != 0 )
        return rc;

    /* there are two conditions under which a physical member
       definition would be incommplete prior to opening the
       column: 1) if the physical column were only forwarded
       within table schema, or 2) if the column were added as
       the result of a file system scan.

       for the column to be writable, it must have had a complete
       member definition from table schema, with a type and an
       assignment expression, or it must have been added as the
       result of an fs scan with a simple reciprocal expression.
       the test for these two cases is for a resolved typedecl
       and an assignment expression. */

    /* nothing more to do if column does not exist
       and member was undeclared, or is declared read-only */
    smbr = phys -> smbr;
    if ( smbr -> td . type_id == 0 || smbr -> expr == NULL )
        return 0;

    /* build fmtdecl */
    fd . td = smbr -> td;
    fd . fmt = 0;

    /* shift to encode chain */
    pr = * self;
    pr . chain = chainEncoding;

    /* resolve the input expression */
    rc = VProdResolveExpr ( & pr, & phys -> in, & desc, & fd, smbr -> expr, false );
    if ( rc == 0 && phys -> in == NULL )
        return RC ( rcVDB, rcCursor, rcOpening, rcColumn, rcUndefined );

    /* NB - at this point, fd and desc
       represent the column's well-defined type */

    /* member name */
    name = smbr -> name -> name . addr;

    /* physical encoding */
    enc = phys -> enc;
    if ( enc == NULL )
        enc = smbr -> type;

    /* build encoding schema in steps:
         in <- page-to-blob
    */
    rc = VSimpleProdMake ( & prod, pr . owned,
        prodSimplePage2Blob, name, & fd, & desc, NULL, phys -> in, chainEncoding );
    if ( rc == 0 && enc != NULL )
    {
        /* in <- p2b <- encoding-func */
        pr . blobbing = true;
        rc = VProdResolveEncodingExpr ( & pr, & prod,
            prod, ( const SPhysEncExpr* ) enc );
        if ( rc == 0 )
        {
            fd = prod -> fd;
            desc = prod -> desc;
        }
    }
    if ( rc == 0 )
    {
        rc = VSimpleProdMake ( & phys -> b2s, pr . owned,
            prodSimpleBlob2Serial, name, & fd, & desc, NULL, prod, chainEncoding );
    }

    return rc;
}
Пример #2
0
/* ResolvePhysical
 *  resolves a physical column
 */
rc_t VProdResolvePhysicalRead ( const VProdResolve *self, VPhysical *phys )
{
    rc_t rc;
    VTypedesc desc;
    VFormatdecl fd;
    VProduction *prod;
    VFunctionProd *bs;
    VCursor *curs = self -> curs;

    const char *name;
    const SExpression *enc;
    const SPhysMember *smbr;

    /* a write cursor would have opened this already */
    if ( curs -> read_only )
    {
        /* open the physical column for read */
        rc = VPhysicalOpenRead ( phys,
            ( VSchema* ) self -> schema, curs -> tbl );
        if ( rc != 0 )
        {
            /* trying to open a column that doesn't exist
               is not an error, but it didn't resolve */
            if ( GetRCState ( rc ) == rcNotFound )
                return 0;

            return rc;
        }
    }

    /* should be completely resolved */
    smbr = phys -> smbr;
    if ( smbr -> td . type_id == 0 )
        return 0;

    /* production name */
    name = smbr -> name -> name . addr;

    /* type information */
    fd . td = smbr -> td;
    fd . fmt = 0;
    rc = VSchemaDescribeTypedecl ( self -> schema, & desc, & fd . td );
    if ( rc != 0 )
        return rc;

    /* create output adapter */
    rc = VPhysicalProdMake ( & prod, self -> owned,
        curs, phys, prodPhysicalOut, name, & fd, & desc );
    if ( rc != 0 )
        return rc;

    /* create byte-swap function with transparent type information */
    rc = VFunctionProdMake ( & bs, self -> owned,
        curs, prodFuncByteswap, name, & fd, & desc, chainDecoding );
    if ( rc != 0 )
        return rc;

    /* set adapter as input to byte swap */
    rc = VectorAppend ( & bs -> parms, NULL, prod );
    if ( rc != 0 )
        return rc;

    /* take byte-swap function as output */
    phys -> out = & bs -> dad;

    /* NB - we now have byte-order native output via an adapter
       it remains to create a decoding path for physical blobs */


    /* create adapter */
    rc = VPhysicalProdMake ( & prod, self -> owned,
        curs, phys, prodPhysicalKCol, name, & fd, & desc );
    if ( rc != 0 )
        return rc;

    /* create serial-to-blob stage */
    rc = VSimpleProdMake ( & prod, self -> owned, self->curs,
        prodSimpleSerial2Blob, name, & fd, & desc, NULL, prod, chainDecoding );
    if ( rc != 0 )
        return rc;

    /* determine physical encoding */
    enc = phys -> enc;
    if ( enc == NULL )
        enc = smbr -> type;

    /* if unencoded */
    if ( enc == NULL )
        phys -> b2p = prod;
    else
    {
        /* the adapter type should be undefined */
        memset ( & prod -> fd, 0, sizeof prod -> fd );
        prod -> desc . intrinsic_bits = prod -> desc . intrinsic_dim = 1;
        prod -> desc . domain = 0;

        /* create decoding production */
        rc = VProdResolveEncodingExpr ( self, & phys -> b2p,
            prod, ( const SPhysEncExpr* ) enc );
    }

    return rc;
}