static rc_t CC VPhysicalLoadSchema ( VPhysical *self, VTypedecl *td, VSchema *schema, const KMDataNode *node ) { rc_t rc; KMDataNodeSchemaFillData pb; pb . node = node; pb . pos = 0; pb . add_v0 = false; /* add stored declaration to cursor schema */ rc = VSchemaParseTextCallback ( schema, "VPhysicalLoadSchema", KMDataNodeFillSchema, & pb ); if ( rc == 0 ) { /* retrieve fully-resolved type attribute */ rc = KMDataNodeReadAttr ( node, "type", pb . buff, sizeof pb . buff, & pb . pos ); if ( rc == 0 ) rc = VSchemaResolveTypedecl ( schema, td, pb . buff ); if ( rc == 0 ) { /* get encoding expression */ rc = KMDataNodeReadAttr ( node, "expr", pb . buff, sizeof pb . buff, & pb . pos ); if ( rc == 0 ) { VTypedecl etd; /* create a new expression object */ rc = VSchemaImplicitPhysEncExpr ( schema, & etd, & self -> enc, pb . buff, "VPhysicalLoadSchema" ); if ( rc != 0 ) { PLOGERR ( klogInt, ( klogInt, rc, "failed to establish column type from '$(expr)'", "expr=%s", pb . buff )); } /* match SPhysical type against stated type */ else if ( ! VTypedeclToTypedecl ( & etd, schema, td, NULL, NULL ) ) { rc = RC ( rcVDB, rcColumn, rcLoading, rcType, rcInconsistent ); PLOGERR ( klogInt, ( klogInt, rc, "inconsistent metadata for column '$(name)'" , "name=%.*s" , ( int ) self -> smbr -> name -> name . size , self -> smbr -> name -> name . addr )); } } else if ( GetRCState ( rc ) == rcNotFound ) { rc = 0; } } } KMDataNodeRelease ( node ); return rc; }
static rc_t VProdResolveColExpr ( const VProdResolve *self, VProduction **out, VFormatdecl *fd, const SSymExpr *x, bool casting ) { rc_t rc; const SNameOverload *sname; const KSymbol *sym = x -> _sym; BSTree ordered; uint32_t i, count; SColumnBestFit buff [ 16 ], * nodes = buff; /* fail if "fd" has a format */ if ( fd -> fmt != 0 ) { PLOGMSG ( klogWarn, ( klogWarn, "illegal cast of column '$(name)'" , "name=%.*s" , ( int ) sym -> name . size , sym -> name . addr )); return 0; } /* allocate nodes for indexing columns */ sname = sym -> u . obj; count = VectorLength ( & sname -> items ); if ( count > sizeof buff / sizeof buff [ 0 ] ) { nodes = malloc ( sizeof * nodes * count ); if ( nodes == NULL ) return RC ( rcVDB, rcProduction, rcResolving, rcMemory, rcExhausted ); } /* insert columns into ordered tree */ BSTreeInit ( & ordered ); for ( i = VectorStart ( & sname -> items ), count += i; i < count; ++ i ) { /* get SColumn */ nodes [ i ] . scol = ( const void* ) VectorGet ( & sname -> items, i ); /* perform type cast and measure distance */ if ( casting ? VTypedeclCommonAncestor ( & nodes [ i ] . scol -> td, self -> schema, & fd -> td, & nodes [ i ] . td, & nodes [ i ] . distance ) : VTypedeclToTypedecl ( & nodes [ i ] . scol -> td, self -> schema, & fd -> td, & nodes [ i ] . td, & nodes [ i ] . distance ) ) { BSTreeInsert ( & ordered, & nodes [ i ] . n, order_column ); } } /* try to resolve each in order */ rc = VProdResolveBestColumn ( self, out, & ordered, x -> alt ); if ( nodes != buff ) free ( nodes ); return rc; }
static bool vdcd_type_cmp( const VSchema *my_schema, VTypedecl * typedecl, const char * to_check ) { VTypedecl type_to_check; rc_t rc = VSchemaResolveTypedecl ( my_schema, &type_to_check, to_check ); if ( rc == 0 ) { return VTypedeclToTypedecl ( typedecl, my_schema, &type_to_check, NULL, NULL ); } return false; }
/* AddSColumn */ static rc_t VViewCursorAddSColumn ( VViewCursor * p_self, uint32_t * p_idx, const SColumn * p_scol, const VTypedecl * p_cast, Vector * p_cx_bind ) { rc_t rc = 0; VColumn *col; /* must be readable */ if ( p_scol -> read == NULL ) { return RC ( rcVDB, rcCursor, rcUpdating, rcColumn, rcWriteonly ); } /* must not already be there - benign error */ col = VCursorCacheGet ( & p_self -> dad . col, & p_scol -> cid ); if ( col != NULL ) { * p_idx = col -> ord; rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, rcExists ); } else { /* make object */ rc = VColumnMake ( & col, p_self -> view -> schema, p_scol ); if ( rc == 0 ) { #if 0 /* open column if cursor open or type unknown */ if ( self -> dad . state >= vcReady || scol -> td . type_id == 0 ) { rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, ?? ); } else { /* check cast of SColumn against requested type this is to handle the case where the column was created incomplete, i.e. with unknown type */ if ( cast != NULL && | VTypedeclToTypedecl ( & scol -> td, self -> schema, cast, & col -> td, NULL ) ) { rc = RC ( rcVDB, rcCursor, rcUpdating, rcColumn, ?? ); } }
/* ToAncestor * cast a typedecl to a size-equivalent ancestor decl * returns true if cast can be performed */ LIB_EXPORT bool CC VDatatypesToAncestor ( const VDatatypes *self, const VTypedecl *to, const VTypedecl *from ) { VTypedecl cast; return VTypedeclToTypedecl ( from, ( const VSchema* ) self, to, & cast, NULL ); }