rc_t VColumnProdMake ( VProduction **prodp, Vector *owned, VColumn *col, int sub, const char *name ) { const SColumn *scol = col -> scol; /* why was this changed to get the column td from SColumn? */ VTypedesc desc; rc_t rc = VSchemaDescribeTypedecl ( col -> schema, & desc, & col -> scol -> td ); if ( rc != 0 ) * prodp = NULL; else { VColumnProd *prod; /* construct an fd because column does not have one */ VFormatdecl fd; fd . td = scol -> td; fd . fmt = 0; rc = VProductionMake ( prodp, owned, sizeof * prod, prodColumn, sub, name, & fd, & desc, NULL, chainEncoding ); if ( rc == 0 ) { prod = ( VColumnProd* ) * prodp; prod -> col = col; } } return rc; }
/* SizeofTypedecl * returns the bit size of type declaration */ LIB_EXPORT rc_t CC VDatatypesSizeofTypedecl ( const VDatatypes *self, bitsz_t *type_size, const VTypedecl *td ) { rc_t rc; if ( type_size == NULL ) rc = RC ( rcSRA, rcSchema, rcAccessing, rcParam, rcNull ); else { VTypedesc desc; rc = VSchemaDescribeTypedecl ( ( const VSchema* ) self, & desc, td ); if ( rc == 0 ) { * type_size = VTypedescSizeof ( & desc ); return 0; } * type_size = 0; } return rc; }
static rc_t matcher_append_type( const char *name, const bool dflt, const uint32_t order, const VSchema *schema, Vector *v ) { rc_t rc = 0; p_mtype t = matcher_init_type( name, dflt, order ); if ( t == NULL ) rc = RC( rcExe, rcNoTarg, rcResolving, rcMemory, rcExhausted ); if ( rc == 0 ) { rc = VectorAppend( v, NULL, t ); if ( rc == 0 ) { rc = VSchemaResolveTypedecl( schema, &(t->type_decl), "%s", name ); if ( rc == 0 ) { rc = VSchemaDescribeTypedecl( schema, &(t->type_desc), &(t->type_decl) ); } } } return rc; }
static rc_t populate_stype_tbl ( BSTree *stype_tbl, const VSchema *schema ) { rc_t rc; uint32_t i; static struct { const char *typename; const char *redact_value; } sensitive_types [] = { /* original SRA types */ { "INSDC:fasta", "N" }, { "INSDC:csfasta", "." }, { "NCBI:2na", "\x00" }, { "NCBI:2cs", "\x00" }, { "NCBI:4na", "\xFF" }, { "NCBI:qual1", "\x00" }, { "NCBI:qual4", "\xFB\xFB\xFB\xFB" }, { "NCBI:isamp1", "\x00\x00\x00" }, { "NCBI:isamp4", "\x00\x00\x00" }, { "NCBI:fsamp1", "\x00\x00\x00" }, { "NCBI:fsamp4", "\x00\x00\x00" }, { "INSDC:dna:text", "N" }, { "INSDC:dna:bin", "\x04" }, { "INSDC:dna:4na", "\xFF" }, { "INSDC:dna:2na", "\x00" }, { "INSDC:color:text", "." }, { "INSDC:color:bin", "\x04" }, { "INSDC:color:2cs", "\x00" }, { "INSDC:quality:phred", "\x00" }, { "INSDC:quality:log_odds", "\x00\x00\x00" } /* signal types TBD */ }; BSTreeInit ( stype_tbl ); for ( rc = 0, i = 0; i < sizeof sensitive_types / sizeof sensitive_types [ 0 ]; ++ i ) { VTypedecl td; const char *decl = sensitive_types [ i ] . typename; rc = VSchemaResolveTypedecl ( schema, & td, decl ); if ( rc == 0 ) { stype_id *n; BSTNode *exist; VTypedesc desc; rc = VSchemaDescribeTypedecl ( schema, & desc, & td ); if ( rc != 0 ) { PLOGERR ( klogInt, (klogInt, rc, "failed to describe type '$(type)'", "type=%s", decl )); break; } n = malloc ( sizeof * n ); if ( n == NULL ) { rc = RC ( rcExe, rcNode, rcAllocating, rcMemory, rcExhausted ); LOGERR ( klogInt, rc, "failed to record sensitive data type" ); break; } n -> redact_value = sensitive_types [ i ] . redact_value; n -> type_id = td . type_id; n -> elem_size = VTypedescSizeof ( & desc ); rc = BSTreeInsertUnique ( stype_tbl, & n -> n, & exist, stype_id_sort ); if ( rc != 0 ) { free ( n ); if ( GetRCState ( rc ) != rcExists ) { LOGERR ( klogInt, rc, "failed to record sensitive data type" ); break; } rc = 0; } } else if ( GetRCState ( rc ) == rcNotFound ) { rc = 0; } else { break; } } return rc; }
/* 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; }
rc_t VProdResolveExpr ( const VProdResolve *self, VProduction **out, VTypedesc *desc, VFormatdecl *fd, const SExpression *expr, bool casting ) { rc_t rc; VProduction *prod; if ( expr == NULL ) { /* report NULL expression, but don't die */ PLOGMSG ( klogWarn, ( klogWarn, "NULL expression in '$(tbl)' table schema" , "tbl=%.*s" , ( int ) self -> stbl -> name -> name . size , self -> stbl -> name -> name . addr )); return 0; } prod = NULL; *out = NULL; #if _DEBUGGING ++ indent_level; VDB_DEBUG (( "%*cresolving expression '%s'\n", indent_level, ' ', VProdResolvePrintExpr ( self, expr ) )); #endif switch ( expr -> var ) { case eParamExpr: /* a script function is making reference to a parameter */ rc = VProdResolveParamExpr ( self, & prod, ( ( const SSymExpr* ) expr ) -> _sym ); assert (rc != -1); break; case eProdExpr: /* return a simple production */ rc = VProdResolveProdExpr ( self, & prod, ( ( const SSymExpr* ) expr ) -> _sym ); assert (rc != -1); break; case eFwdExpr: /* handle an implicit or overridden reference */ rc = VProdResolveFwdExpr ( self, & prod, fd, ( const SSymExpr* ) expr, casting ); assert (rc != -1); break; case eColExpr: /* return a column production */ rc = VProdResolveColExpr ( self, & prod, fd, ( const SSymExpr* ) expr, casting ); assert (rc != -1); break; case ePhysExpr: /* return a physical production */ rc = VProdResolvePhysExpr ( self, & prod, ( ( const SSymExpr* ) expr ) -> _sym ); assert (rc != -1); break; case eScriptExpr: /* create a script function */ rc = VProdResolveScriptExpr ( self, & prod, fd, ( const SFuncExpr* ) expr ); assert (rc != -1); break; case eFuncExpr: /* create an external function */ rc = VProdResolveFuncExpr ( self, & prod, fd, ( const SFuncExpr* ) expr ); assert (rc != -1); break; case eCastExpr: /* perform an explicit cast */ rc = VProdResolveCastExpr ( self, & prod, ( const SBinExpr* ) expr ); assert (rc != -1); break; case eCondExpr: /* run left and right expressions in order until exit condition */ rc = VProdResolveExpr ( self, out, desc, fd, ( ( const SBinExpr* ) expr ) -> left, casting ); assert (rc != -1); if ( ( rc == 0 && * out == NULL ) || self -> discover_writable_columns ) { rc = VProdResolveExpr ( self, out, desc, fd, ( ( const SBinExpr* ) expr ) -> right, casting ); assert (rc != -1); } #if _DEBUGGING -- indent_level; #endif return rc; default: /* report bad expression, but don't die */ PLOGMSG ( klogWarn, ( klogWarn, "unrecognized expression in '$(tbl)' table schema" , "tbl=%.*s" , ( int ) self -> stbl -> name -> name . size , self -> stbl -> name -> name . addr )); #if _DEBUGGING -- indent_level; #endif return 0; } /* guard against returns of NULL or FAILED_PRODUCTION */ if ( rc == 0 && prod > FAILED_PRODUCTION ) { VDB_DEBUG ( ("%*cresolved expression '%s'\n", indent_level, ' ', VProdResolvePrintExpr ( self, expr ) ) ); /* returned production must be on requested chain */ if ( ( prod -> chain & self -> chain ) == 0 ) { rc = RC ( rcVDB, rcProduction, rcResolving, rcSchema, rcInconsistent ); VDB_DEBUG ( ( "%*cPRODUCTION RESOLVED ON WRONG FORK: %R\n", indent_level, ' ', rc ) ); } else { /* fix uncommitted production chain */ if ( prod -> chain == chainUncommitted ) prod -> chain = self -> chain; /* test for type compatibility - modifies "fd" */ if ( casting ? VFormatdeclCommonAncestor ( & prod -> fd, self -> schema, fd, fd, NULL ) : VFormatdeclToFormatdecl ( & prod -> fd, self -> schema, fd, fd, NULL ) ) { /* if no type description is requested, we're done */ if ( desc == NULL ) * out = prod; else { /* otherwise, create a type description */ rc = VSchemaDescribeTypedecl ( self -> schema, desc, & fd -> td ); assert (rc != -1); if ( rc != 0 ) VDB_DEBUG ( ( "%*cREQUESTED TYPE CANNOT BE DESCRIBED: %R\n", indent_level, ' ', rc ) ); else * out = prod; } } else { #if _DEBUGGING char from [ 128 ] = "", to [ 128 ] = ""; VTypedeclToText ( & prod -> fd . td, self -> schema, from, sizeof from ); VTypedeclToText ( & fd -> td, self -> schema, to, sizeof to ); VDB_DEBUG ( ( "%*cexpression '%s' cannot be %s from '%s' to '%s'\n" , indent_level, ' ' , VProdResolvePrintExpr ( self, expr ) , casting ? "cast" : "typed" , from , to ) ); #endif } } } else if ( rc != 0 ) { VDB_DEBUG ( ( "failed to resolve expression '%s' prod %p %R\n", VProdResolvePrintExpr ( self, expr ), prod, rc ) ); } else if ( prod == NULL ) { VDB_DEBUG ( ( "expression '%s' was not resolved\n", VProdResolvePrintExpr ( self, expr ) ) ); } else { VDB_DEBUG ( ( "expression '%s' returned FAILED_PRODUCTION\n", VProdResolvePrintExpr ( self, expr ) ) ); } #if _DEBUGGING -- indent_level; #endif return rc; }