/*{ ** Name: ops_deallocate - deallocate resources for an optimization ** ** Description: ** This routine will deallocate the resources used for an optimization. ** Resources include any memory requested from the optimizer memory pool ** and any RDF cache objects which were locked in the global range ** table ** ** Inputs: ** global ptr to global state variable ** report TRUE if errors should be reported ** via the user's control block. ** partial_dbp partial deallocation required for ** statement within a procedure ** ** Outputs: ** Returns: ** VOID ** Exceptions: ** none ** ** Side Effects: ** memory resources released, RDF unfixed, ** QSF query tree memory released ** ** History: ** 29-jun-86 (seputis) ** initial creation ** 8-nov-88 (seputis) ** if no query run trace point is set then destroy the QP since ** SCF assumes optimizer cleans up after error ** 8-nov-88 (seputis) ** turn off CPU accounting if was off originally ** 28-jan-91 (seputis) ** added support for OPF ACTIVE flag ** 20-jul-93 (ed) ** changed name ops_lock for solaris, due to OS conflict ** 29-jul-93 (andre) ** rdr_types_mask must be initialized (to RDR_RELATION) before ** calling RDF_UNFIX. Otherwise RDF may end up complaining because we ** ask it to destroy a relation cache entry while RDR_PROCEDURE bit is ** set. ** 12-aug-93 (swm) ** Cast first parameter of CSaltr_session() to CS_SID to match ** revised CL interface specification. ** 02-Jun-1997 (shero03) ** Update the saved rdf_info_block after calling RDF. ** 02-Aug-2001 (hanal04) Bug 105360 INGSRV 1505 ** Plug the RDF memory leak introduced by inkdo01's new ** function oph_temphist(). ** 17-Dec-2003 (jenjo02) ** Added (CS_SID)NULL to CScnd_signal prototype. ** 6-Feb-2006 (kschendel) ** Fix some squirrely looking code that purported to avoid dangling ** references, but didn't really. (No symptoms known.) ** 14-nov-2007 (dougi) ** Add support for cached dynamic query plans. ** 20-may-2008 (dougi) ** Add support for table procedures. ** 29-may-2009 (wanfr01) Bug 122125 ** Need to add dbid to cache_dynamic queries for db uniqueness */ VOID ops_deallocate( OPS_STATE *global, bool report, bool partial_dbp) { DB_STATUS finalstatus; /* this status is returned to the user ** - it will contain the first error ** during resource deallocation */ DB_ERROR error; /* error code from offending facility */ finalstatus = E_DB_OK; error.err_code = 0; { /* close any fixed RDF objects - deallocate prior to closing the ** global memory stream */ OPV_IGVARS gvar; /* index into global range variable ** table */ OPV_GRT *gbase; /* ptr to base of array of ptrs ** to global range table elements */ OPV_IGVARS maxgvar; /* number of global range table ** elements allocated */ RDF_CB *rdfcb; /* ptr to rdf control block used ** unfix the relation info */ OPV_GBMVARS *rdfmap; /* ptr to map of global range ** variables which have RDF info ** fixed */ gbase = global->ops_rangetab.opv_base; maxgvar = global->ops_rangetab.opv_gv; rdfcb = &global->ops_rangetab.opv_rdfcb; rdfmap = &global->ops_rangetab.opv_mrdf; /* ** rdr_types_mask needs to be initialized - since we will be unfixing ** relation entries, RDR_RELATION seems like a good choice, although 0 ** would suffice as well */ rdfcb->rdf_rb.rdr_types_mask = RDR_RELATION; if (global->ops_cstate.opc_relation) { /* OPC allocates a RDF descriptor for cursors so deallocate ** if this is the case */ DB_STATUS opcrdfstatus; /* RDF return status */ rdfcb->rdf_info_blk = global->ops_cstate.opc_relation; opcrdfstatus = rdf_call( RDF_UNFIX, (PTR)rdfcb ); if ( (DB_FAILURE_MACRO(opcrdfstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = opcrdfstatus; error.err_code = rdfcb->rdf_error.err_code; } global->ops_cstate.opc_relation = NULL; } if (maxgvar) { for ( gvar = -1; (gvar = BTnext((i4)gvar, (char *)rdfmap, (i4)maxgvar)) >=0;) { OPV_GRV *gvarp; /* ptr to global range variable to ** be deallocated */ if ((gvarp = gbase->opv_grv[gvar]) /* NULL if not allocated */ && (gvarp->opv_relation) /* not NULL if RDF has been ** called for this range variable */ && !(gvarp->opv_gmask & OPV_TPROC) /* not table procedure */ ) { /* if this element has been allocated and if it has an RDF ** cache element associated with it */ DB_STATUS rdfstatus; /* RDF return status */ gbase->opv_grv[gvar] = NULL; /* so we do not try to deallocate ** twice in case of an error */ rdfcb->rdf_info_blk = gvarp->opv_relation; rdfstatus = rdf_call( RDF_UNFIX, (PTR)rdfcb ); if ( (DB_FAILURE_MACRO(rdfstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = rdfstatus; error.err_code = rdfcb->rdf_error.err_code; } gvarp->opv_relation = NULL; } if ((gvarp) && (gvarp->opv_ttmodel)) { /* if this element has been allocated and if it has an RDF ** cache element associated with a persistent table ** which provides histogram models. */ DB_STATUS rdfstatus; /* RDF return status */ rdfcb->rdf_info_blk = gvarp->opv_ttmodel; gvarp->opv_ttmodel = NULL; rdfstatus = rdf_call( RDF_UNFIX, (PTR)rdfcb ); if ( (DB_FAILURE_MACRO(rdfstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = rdfstatus; error.err_code = rdfcb->rdf_error.err_code; } } } global->ops_rangetab.opv_gv = 0; } } if (partial_dbp) return; /* only deallocate the global range table ** for DBP, and keep the memory streams ** until the end */ if (global->ops_estate.opn_statistics && global->ops_estate.opn_reset_statistics) { /* statistics CPU accounting was turned on, and needs to be reset */ STATUS cs_status; i4 turn_off; turn_off = FALSE; /* turn off accounting */ global->ops_estate.opn_statistics = FALSE; cs_status = CSaltr_session((CS_SID)0, CS_AS_CPUSTATS, (PTR)&turn_off); if (cs_status != OK) { finalstatus = E_DB_ERROR; error.err_code = cs_status; } } /* deallocate ULM memory stream */ if (global->ops_mstate.ops_streamid == NULL) /* non-zero if allocated */ { /* check if ULM stream does not exist then this deallocation has ** already occurred so just return */ return; } else { DB_STATUS ulm1status;/* ULM return status */ global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_streamid; /* ulm will NULL ops_streamid */ ulm1status = ulm_closestream( &global->ops_mstate.ops_ulmrcb ); if ( (DB_FAILURE_MACRO(ulm1status)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = ulm1status; error.err_code = global->ops_mstate.ops_ulmrcb.ulm_error.err_code; } } /* deallocate ULM temp buffer memory stream */ if ( global->ops_mstate.ops_tstreamid ) /* non-zero if allocated */ { DB_STATUS ulm2status; /* ULM return status */ global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_tstreamid; /* ulm will NULL ops_tstreamid */ ulm2status = ulm_closestream( &global->ops_mstate.ops_ulmrcb ); if ( (DB_FAILURE_MACRO(ulm2status)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = ulm2status; error.err_code = global->ops_mstate.ops_ulmrcb.ulm_error.err_code; } } /* deallocate OPC ULM buffer memory stream */ if ( global->ops_mstate.ops_sstreamid ) /* non-zero if allocated */ { DB_STATUS ulm3status; /* ULM return status */ global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_sstreamid; /* ulm will NULL ops_sstreamid */ ulm3status = ulm_closestream( &global->ops_mstate.ops_ulmrcb ); if ( (DB_FAILURE_MACRO(ulm3status)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = ulm3status; error.err_code = global->ops_mstate.ops_ulmrcb.ulm_error.err_code; } } if (!report #ifdef OPT_F032_NOEXECUTE || /* if trace flag is set then cleanup QSF memory since optimizer will ** generate an error to SCF and SCF assumes optimizer will cleanup */ (global->ops_cb->ops_check && (opt_strace( global->ops_cb, OPT_F032_NOEXECUTE) || opt_strace( global->ops_cb, OPT_F023_NOCOMP) ) ) #endif ) { /* an error or an asychronous abort has occurred so destroy the plan ** or shared plan , FIXME destroy the shared plan in the earlier ** exception handler */ DB_STATUS qsfqpstatus; /* QSF return status */ if(global->ops_qpinit) { /* deallocate QSF object for query plan if another error has occurred ** - in this case OPC has already created a new QP handle and has ** gotten a lock on it */ STRUCT_ASSIGN_MACRO(global->ops_caller_cb->opf_qep, global->ops_qsfcb.qsf_obj_id); /* get ** query plan id */ global->ops_qsfcb.qsf_lk_id = global->ops_qplk_id; /* get lock id for ** QSF */ qsfqpstatus = ops_qsfdestroy(global); /* destroy the query plan */ if ( (DB_FAILURE_MACRO(qsfqpstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = qsfqpstatus; error.err_code = global->ops_qsfcb.qsf_error.err_code; } } else { /* OPC has not been reached so need to check for shared query plan */ if (!global->ops_procedure) { /* get query tree if it has not already been retrieved */ qsfqpstatus = ops_gqtree(global); if ( (DB_FAILURE_MACRO(qsfqpstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = qsfqpstatus; error.err_code = global->ops_qsfcb.qsf_error.err_code; } } if (global->ops_qheader && (global->ops_qheader->pst_mask1 & PST_RPTQRY)) { /* shared query plan possible */ if (global->ops_procedure->pst_flags & PST_REPEAT_DYNAMIC) { char *p; global->ops_qsfcb.qsf_obj_id.qso_lname = sizeof(DB_CURSOR_ID) + sizeof(i4); MEfill(sizeof(global->ops_qsfcb.qsf_obj_id.qso_name), 0, global->ops_qsfcb.qsf_obj_id.qso_name); MEcopy((PTR)&global->ops_procedure-> pst_dbpid.db_cursor_id[0], sizeof (global->ops_procedure-> pst_dbpid.db_cursor_id[0]), (PTR)global->ops_qsfcb.qsf_obj_id.qso_name); p = (char *) global->ops_qsfcb.qsf_obj_id.qso_name + 2*sizeof(i4); MEcopy((PTR)"qp", sizeof("qp"), p); p = (char *) global->ops_qsfcb.qsf_obj_id.qso_name + sizeof(DB_CURSOR_ID); I4ASSIGN_MACRO(global->ops_caller_cb->opf_udbid, *(i4 *) p); } else /* must be proc or regular repeat query */ { global->ops_qsfcb.qsf_obj_id.qso_lname = sizeof (global->ops_procedure->pst_dbpid); MEcopy((PTR)&global->ops_procedure->pst_dbpid, sizeof (global->ops_procedure->pst_dbpid), (PTR)&global->ops_qsfcb.qsf_obj_id.qso_name[0]); } global->ops_qsfcb.qsf_obj_id.qso_type = QSO_QP_OBJ; global->ops_qsfcb.qsf_lk_state = QSO_SHLOCK; qsfqpstatus = qsf_call(QSO_GETHANDLE, &global->ops_qsfcb); if (DB_SUCCESS_MACRO(qsfqpstatus)) { qsfqpstatus = ops_qsfdestroy( global ); if ( (DB_FAILURE_MACRO(qsfqpstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = qsfqpstatus; error.err_code = global->ops_qsfcb.qsf_error.err_code; } } else if (global->ops_qsfcb.qsf_error.err_code != E_QS0019_UNKNOWN_OBJ) { /* if object is not found then this is not a shared query */ finalstatus = qsfqpstatus; error.err_code = global->ops_qsfcb.qsf_error.err_code; } } } } /* release QSF memory allocated to query tree, make sure that this ** is done after the QP has been processed since pst_rptqry is still ** needed for above block */ { DB_STATUS qsfstatus; /* QSF return status */ STRUCT_ASSIGN_MACRO(global->ops_caller_cb->opf_query_tree, global->ops_qsfcb.qsf_obj_id); /* get ** query tree id */ global->ops_qsfcb.qsf_lk_id = global->ops_lk_id; /* get lock id for ** QSF */ qsfstatus = ops_qsfdestroy( global ); if ( (DB_FAILURE_MACRO(qsfstatus)) && (DB_SUCCESS_MACRO(finalstatus)) ) { finalstatus = qsfstatus; error.err_code = global->ops_qsfcb.qsf_error.err_code; } } /* signal that the session is exiting OPF and that another thread may enter */ if (global->ops_cb->ops_smask & OPS_MCONDITION) { DB_STATUS lockstatus; OPG_CB *servercb; servercb = global->ops_cb->ops_server; global->ops_cb->ops_smask &= (~OPS_MCONDITION); lockstatus = ops_exlock(global->ops_caller_cb, &servercb->opg_semaphore); /* check if server ** thread is available, obtain ** semaphore lock on critical variable */ servercb->opg_activeuser--; /* since exit is about to occur, and memory ** has already been deallocated, allow another ** user to enter OPF */ servercb->opg_waitinguser--; /* since exit is about to occur, and memory ** has already been deallocated, allow another ** user to enter OPF */ if (DB_FAILURE_MACRO(lockstatus) && (DB_SUCCESS_MACRO(finalstatus))) { finalstatus = lockstatus; error.err_code = global->ops_caller_cb->opf_errorblock.err_data; } else { if (servercb->opg_waitinguser > servercb->opg_activeuser) { STATUS csstatus; csstatus = CScnd_signal(&servercb->opg_condition, (CS_SID)NULL); /* signal only if some users are waiting */ if ((csstatus != OK) && (DB_SUCCESS_MACRO(finalstatus))) { finalstatus = E_DB_ERROR; error.err_code = csstatus; } } lockstatus = ops_unlock(global->ops_caller_cb, &servercb->opg_semaphore); /* check if server ** thread is available */ if (DB_FAILURE_MACRO(lockstatus) && (DB_SUCCESS_MACRO(finalstatus))) { finalstatus = lockstatus; error.err_code = global->ops_caller_cb->opf_errorblock.err_data; } } } if (DB_FAILURE_MACRO(finalstatus)) { if (report) opx_verror( finalstatus, E_OP0084_DEALLOCATION, error.err_code); /* report ** error and generate an exception */ else opx_rverror(global->ops_cb->ops_callercb, finalstatus, E_OP0084_DEALLOCATION, error.err_code); /* report error only but do not generate an ** exception */ } }
/*{ ** Name: ops_init - initialize structures needed for optimization ** ** Description: ** This routine will initialize the "global state" variable which contains ** all information for the optimization of this query for this session. ** ** Inputs: ** global ptr to global state variable ** .ops_cb ptr to session control block ** .ops_caller_cb ptr to same object as opf_cb ** opf_cb caller's control block ** ** Outputs: ** global all components initialized ** Returns: ** E_DB_OK, E_DB_ERROR ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 24-feb-86 (seputis) ** initial creation ** 26-nov-90 (stec) ** Added initialization of ops_prbuf in OPS_STATE struct. ** 28-dec-90 (stec) ** Changed initialization of print buffer; ops_prbuf has been ** removed, opc_prbuf in OPC_STATE struct will be initialized ** instead. ** 28-jan-91 (seputis) ** added support for OPF ACTIVE FLAG ** 11-jun-91 (seputis) ** ifdef distributed code until header files merge ** 04-sep-92 (fpang) ** Fixed initialization of rdr_r1_distrib. ** 27-apr-95 (inkdo01) ** Init ops_osubquery to NULL ** 26-nov-96 (inkdo01) ** Allow users OPF memory equal to 1.5 config.dat definition. That way ** the boundary users don't dictate the size of the mem pool (it being ** highly unlikely that all users will want big memory simultaneously). ** 12-dec-96 (inkdo01) ** Shamed into doing the above change more rigourously. Now a new ** config parm (opf_maxmemf) defines the proportion of the OPF pool ** available to any session. This gets computed in opsstartup, so the ** code added for the previous change is now removed. ** 20-jun-1997 (nanpr01) ** Initialize the rdf_info_blk to NULL. This is specially required ** for query without a base table. ** 23-oct-98 (inkdo01) ** Init opc_retrowno, opc_retrowoff for row producing procs. ** 27-oct-98 (inkdo01) ** Quicky afterthought to init opc_retrow_rsd. ** 11-oct-2006 (hayke02) ** Send E_OP0002_NOMEMORY to errlog.log. This change fixes bug 116309. ** 25-Nov-2008 (hanal04) Bug 121248 ** Initialise new caller_ref field in the opv_rdfcb to avoid SEGVs ** later on. ** 25-feb-10 (smeke01) b123333 ** As the NULL-ing of ops_trace.opt_conode has been remmoved from ** opt_printCostTree() we need to make sure it is initialised here ** prior to any call of opt_cotree() by trace point op145 (set qep). [@history_line@]... [@history_template@]... */ VOID ops_init( OPF_CB *opf_cb, OPS_STATE *global) { /* initialize some variables so that error recovery can determine which ** resources to free (i.e. which resources have been successfully ** allocated) ** - this must be done prior to the allocation of a memory stream since ** the streamid is used to indicate whether any resources at all have ** been allocated */ global->ops_cb = (OPS_CB *)opf_cb->opf_scb; /* save session control block */ /* global->ops_caller_cb initialized before exception handler established */ global->ops_adfcb = global->ops_cb->ops_adfcb; /* get current ADF control ** block for session */ if (global->ops_adfcb) { /* init adf_constants since this may uninitialized after the ** previous query executed by QEF, and may cause ADF to write ** to deallocated memory */ global->ops_adfcb->adf_constants = (ADK_CONST_BLK *)NULL; } global->ops_qheader = NULL; global->ops_statement = NULL; global->ops_procedure = NULL; /* - NULL indicates that QSF query ** tree has not been fixed ** - used by error handling to determine ** if this resource needs to be ** deallocated */ /* global->ops_lk_id initialized below */ /* global->ops_parmtotal initialized below */ global->ops_mstate.ops_streamid = NULL;/* init so deallocate routines do not ** access unless it is necessary */ global->ops_mstate.ops_sstreamid = NULL; /* init so deallocate routines do ** not access unless it is necessary */ global->ops_mstate.ops_tstreamid = NULL; /* the temporary buffer stream is ** allocated only when needed */ global->ops_subquery = NULL; /* initialize the subquery list */ global->ops_osubquery = NULL; /* initialise pointer used in opt_printCostTree() for tracing CO node */ global->ops_trace.opt_conode = NULL; /* global->ops_astate initialized by aggregate processing phase */ /* global->ops_estate initialized by joinop processing phase */ global->ops_qpinit = FALSE; /* query plan object not allocated yet*/ global->ops_cstate.opc_prbuf = NULL;/* trace print buffer ptr. */ global->ops_cstate.opc_relation = NULL; /* init relation descriptor ** so deallocation routine will ** only be done if OPC allocates ** an RDF descriptor */ global->ops_cstate.opc_retrowno = -1; global->ops_cstate.opc_retrowoff = 0; /* result row buffer init */ global->ops_cstate.opc_retrow_rsd = (PST_QNODE *) NULL; ops_qinit(global, (PST_STATEMENT *)NULL); /* init range table only for resource ** deallocation */ { /* allocate a memory stream to be used by the optimizer ** - the streamid PTR was initialized to NULL earlier - prior to the ** establishment of the exception handler so that it can be used ** to indicate to the cleanup routines that no resources have been ** allocated */ DB_STATUS ulmstatus; global->ops_mstate.ops_ulmrcb.ulm_facility = DB_OPF_ID; /* identifies optimizer ** so that ULM can make SCF calls on ** behave of the optimizer */ global->ops_mstate.ops_ulmrcb.ulm_poolid = global->ops_cb->ops_server->opg_memory; /* poolid of OPF ** obtained at server startup time */ global->ops_mstate.ops_ulmrcb.ulm_blocksize = 0; /* use default for ** now */ global->ops_mstate.ops_memleft =global->ops_cb->ops_alter.ops_maxmemory; /* save amount of memory which can be ** used by this session */ global->ops_mstate.ops_mlimit = global->ops_mstate.ops_memleft / 10; /* if 10% of memory is left trigger ** garbage collection routines */ global->ops_mstate.ops_ulmrcb.ulm_memleft = &global->ops_mstate.ops_memleft; /* ** and point to it for ULM */ global->ops_mstate.ops_ulmrcb.ulm_streamid_p = &global->ops_mstate.ops_streamid; /* ** Where ULM will return streamid */ global->ops_mstate.ops_ulmrcb.ulm_flags = ULM_PRIVATE_STREAM; /* Allocate private, thread-safe streams */ ulmstatus = ulm_openstream(&global->ops_mstate.ops_ulmrcb); /* get memory for the ** optimizer */ if (DB_FAILURE_MACRO(ulmstatus)) { opx_lerror(E_OP0002_NOMEMORY, 0, 0, 0, 0, 0); opx_verror( ulmstatus, E_OP0002_NOMEMORY, global->ops_mstate.ops_ulmrcb.ulm_error.err_code); } global->ops_mstate.ops_tptr = NULL; /* init temp buffer ptr from ** ops_tstreamid*/ global->ops_mstate.ops_tsize = 0; /* init temp buffer size */ /* ULM has set ops_streamid to the ** streamid for "global optimizer" ** memory, note the enumeration will ** create other streamids for "local" ** memory but still use the ** same control ops_ulmrcb ** in order to decrement and ** increment the same "memleft" counter */ /* initialize ptrs to full size array of ptrs, allocate once for DB procedure ** or 4K will be wasted for each assignment statement and query */ global->ops_mstate.ops_trt = NULL; global->ops_mstate.ops_tft = NULL; global->ops_mstate.ops_tat = NULL; global->ops_mstate.ops_tet = NULL; global->ops_mstate.ops_tbft = NULL; global->ops_mstate.ops_usemain = FALSE; /* disable redirection of ** memory allocation */ global->ops_mstate.ops_totalloc = 0; /* init stats fields */ global->ops_mstate.ops_countalloc = 0; global->ops_mstate.ops_count2kalloc = 0; global->ops_mstate.ops_recover = 0; } { /* get the procedure from QSF */ DB_STATUS qsfstatus; /* QSF return status */ qsfstatus = ops_gqtree(global); /* get procedure from QSF */ if (DB_FAILURE_MACRO(qsfstatus)) opx_verror( qsfstatus, E_OP0085_QSO_LOCK, global->ops_qsfcb.qsf_error.err_code); /* report error */ } { /* initialize the RDF control block used to fetch information for ** the global range table */ RDR_RB *rdfrb; /* ptr to RDF request block */ rdfrb = &global->ops_rangetab.opv_rdfcb.rdf_rb; global->ops_rangetab.opv_rdfcb.rdf_info_blk = NULL; global->ops_rangetab.opv_rdfcb.caller_ref = (RDR_INFO **)NULL; rdfrb->rdr_db_id = global->ops_cb->ops_dbid; /* save the data base id ** for this session only */ rdfrb->rdr_unique_dbid = global->ops_cb->ops_udbid; /* save unique ** dbid for all sessions */ rdfrb->rdr_session_id = global->ops_cb->ops_sid; /* save the session id ** for this session */ rdfrb->rdr_fcb = global->ops_cb->ops_server->opg_rdfhandle; /* save the ** poolid for the RDF info */ if (global->ops_cb->ops_smask & OPS_MDISTRIBUTED) rdfrb->rdr_r1_distrib = DB_3_DDB_SESS; else rdfrb->rdr_r1_distrib = 0; if (global->ops_cb->ops_smask & OPS_MCONDITION) rdfrb->rdr_2types_mask = RDR2_TIMEOUT; /* indicate that timeout should ** occur on all RDF accesses */ else rdfrb->rdr_2types_mask = 0; rdfrb->rdr_instr = RDF_NO_INSTR; } }