/* ** Name: psl_lm5_setlockmode_distr()- perform semantic actions for SETLOCKMODE ** production. ** ** Description: ** perform semantic action for SETLOCKMODE production in SQL ** grammar for distributed thread. SET LOCKMODE SESSION ... TIMEOUT ** is handled by QEF in the distributed server by timing out on ** queries to LDB; all other SET LOCKMODE ON TABLE options are sent ** to QEF to pass on to LDB as text. ** ** Inputs: ** sess_cb ptr to a PSF session CB ** pss_distrib DB_3_DDB_SESS if distributed thread ** pss_stmt_flags PSS_SET_LOCKMODE_SESS if SET LOCKMODE SESSION ** (distributed thread only) ** scanbuf_ptr ptr into scanner buffer containing text of ** SET LOCKMODE statement ** xlated_qry For query text buffering ** ** Outputs: ** err_blk will be filled in if an error occurs ** ** Returns: ** E_DB_{OK, ERROR} ** ** History: ** 5-mar-1991 (barbara) ** Extracted from 6.4 Star grammar for Sybil. ** 4-dec-92 (barbara) ** If call to QEF fails, error has already been reported. PSF must ** set psq_error (or SCF will complain); however, we want to avoid ** PSF retry so we also set PSQ_REDO to pretend we are already in ** server retry. ** 06-oct-93 (barbara) ** Fix for bug 53492. SET LOCKMODE SESSION ... is now supported for ** options other than TIMEOUT. */ DB_STATUS psl_lm5_setlockmode_distr( PSS_SESBLK *sess_cb, char *scanbuf_ptr, PSS_Q_XLATE *xlated_qry, PSQ_CB *psq_cb) { QEF_RCB *qef_rb; DB_STATUS status; DB_ERROR *err_blk = &psq_cb->psq_error; if (sess_cb->pss_distrib & DB_3_DDB_SESS) { qef_rb = (QEF_RCB *) sess_cb->pss_object; if ( sess_cb->pss_stmt_flags & PSS_SET_LOCKMODE_SESS && qef_rb->qef_r3_ddb_req.qer_d14_ses_timeout != DMC_C_UNKNOWN) { status = qef_call(QED_SES_TIMEOUT, ( PTR ) qef_rb); if (DB_FAILURE_MACRO(status)) { err_blk->err_code = E_PS0001_USER_ERROR; /* ** Make it appear as if query is already in retry so that ** psq_call won't retry this failed statement. */ psq_cb->psq_flag |= PSQ_REDO; return(status); } } else { status = psq_x_add(sess_cb, (char *)scanbuf_ptr, &sess_cb->pss_ostream, xlated_qry->pss_buf_size, &xlated_qry->pss_q_list, (i4) ((char *) sess_cb->pss_endbuf - scanbuf_ptr), " ", (char *) sess_cb->pss_endbuf, (char *) NULL, err_blk); if (DB_FAILURE_MACRO(status)) { return(status); } qef_rb->qef_r3_ddb_req.qer_d4_qry_info.qed_q4_pkt_p = xlated_qry->pss_q_list.pss_head; if (~sess_cb->pss_stmt_flags & PSS_SET_LOCKMODE_SESS) { status = qef_call(QED_QRY_FOR_LDB, ( PTR ) qef_rb); } else { status = qef_call(QED_SET_FOR_RQF, ( PTR ) qef_rb); } if (DB_FAILURE_MACRO(status)) { err_blk->err_code = E_PS0001_USER_ERROR; /* ** Make it appear as if query is already in retry so that ** psq_call won't retry this failed statement. */ psq_cb->psq_flag |= PSQ_REDO; return(status); } } /* ** we are done; deallocate the memory as it will not be used by ** anyone else */ status = psf_mclose(sess_cb, &sess_cb->pss_ostream, err_blk); if (DB_FAILURE_MACRO(status)) return (status); /* ** make sure psq_parseqry() realizes that the stream has been closed */ sess_cb->pss_ostream.psf_mstream.qso_handle = (PTR) NULL; } return (E_DB_OK); }
/* ** Name: scs_put_sess_dbpriv - put dbprivs into session values ** ** Description: ** This takes a SCS_DBPRIV structure and assigns values appropriately ** to the SCB values. ** ** Inputs: ** scb - SCB ** ** dbpriv - Dbprivilegs to be assigned ** ** History: ** 18-mar-94 (robf) ** Created ** 21-mar-94 (robf) ** Change session priority if current value would exceed ** the new limit. */ DB_STATUS scs_put_sess_dbpriv( SCD_SCB *scb, SCS_DBPRIV *dbpriv) { DB_STATUS status=E_DB_OK; QEF_RCB qef_cb; QEF_ALT qef_alt[7]; scb->scb_sscb.sscb_ics.ics_ctl_dbpriv = dbpriv->ctl_dbpriv; scb->scb_sscb.sscb_ics.ics_fl_dbpriv = dbpriv->fl_dbpriv; scb->scb_sscb.sscb_ics.ics_qrow_limit = dbpriv->qrow_limit; scb->scb_sscb.sscb_ics.ics_qdio_limit = dbpriv->qdio_limit; scb->scb_sscb.sscb_ics.ics_qcpu_limit = dbpriv->qcpu_limit; scb->scb_sscb.sscb_ics.ics_qpage_limit = dbpriv->qpage_limit; scb->scb_sscb.sscb_ics.ics_qcost_limit = dbpriv->qcost_limit; scb->scb_sscb.sscb_ics.ics_idle_limit = dbpriv->idle_limit; scb->scb_sscb.sscb_ics.ics_connect_limit = dbpriv->connect_limit; scb->scb_sscb.sscb_ics.ics_priority_limit= dbpriv->priority_limit; /* ** Ensure current values follow limits. */ if ((DBPR_IDLE_LIMIT & dbpriv->ctl_dbpriv) && (DBPR_IDLE_LIMIT & dbpriv->fl_dbpriv) && (scb->scb_sscb.sscb_ics.ics_cur_idle_limit> dbpriv->idle_limit || scb->scb_sscb.sscb_ics.ics_cur_idle_limit <=0)) { scb->scb_sscb.sscb_ics.ics_cur_idle_limit= dbpriv->idle_limit; } if ((DBPR_CONNECT_LIMIT & dbpriv->ctl_dbpriv) && (DBPR_CONNECT_LIMIT & dbpriv->fl_dbpriv) && (scb->scb_sscb.sscb_ics.ics_cur_connect_limit> dbpriv->connect_limit || scb->scb_sscb.sscb_ics.ics_cur_connect_limit <=0)) { scb->scb_sscb.sscb_ics.ics_cur_connect_limit= dbpriv->connect_limit; } if ((DBPR_PRIORITY_LIMIT & dbpriv->ctl_dbpriv) && (DBPR_PRIORITY_LIMIT & dbpriv->fl_dbpriv)) { if (scb->scb_sscb.sscb_ics.ics_cur_priority > dbpriv->priority_limit) { /* ** Current session priority would exceed the limit so we ** change the priority lower to be within the limit */ (VOID)scs_set_priority(scb, dbpriv->priority_limit); } } /* ** Call QEF to stash the session's database privileges ** in the QEF session control block. Note that QEF keeps ** it's own copy of the database privileges. */ qef_alt[0].alt_code = QEC_DBPRIV; qef_alt[0].alt_value.alt_u_i4 = scb->scb_sscb.sscb_ics.ics_fl_dbpriv; qef_alt[1].alt_code = QEC_QROW_LIMIT; qef_alt[1].alt_value.alt_i4 = scb->scb_sscb.sscb_ics.ics_qrow_limit; qef_alt[2].alt_code = QEC_QDIO_LIMIT; qef_alt[2].alt_value.alt_i4 = scb->scb_sscb.sscb_ics.ics_qdio_limit; qef_alt[3].alt_code = QEC_QCPU_LIMIT; qef_alt[3].alt_value.alt_i4 = scb->scb_sscb.sscb_ics.ics_qcpu_limit; qef_alt[4].alt_code = QEC_QPAGE_LIMIT; qef_alt[4].alt_value.alt_i4 = scb->scb_sscb.sscb_ics.ics_qpage_limit; qef_alt[5].alt_code = QEC_QCOST_LIMIT; qef_alt[5].alt_value.alt_i4 = scb->scb_sscb.sscb_ics.ics_qcost_limit; qef_cb.qef_length = sizeof(QEF_RCB); qef_cb.qef_type = QEFRCB_CB; qef_cb.qef_ascii_id = QEFRCB_ASCII_ID; qef_cb.qef_sess_id = scb->cs_scb.cs_self; qef_cb.qef_asize = 6; qef_cb.qef_alt = qef_alt; qef_cb.qef_eflag = QEF_EXTERNAL; qef_cb.qef_cb = scb->scb_sscb.sscb_qescb; status = qef_call(QEC_ALTER, &qef_cb); if (status) { sc0e_0_put(qef_cb.error.err_code, 0); scd_note(status, DB_SCF_ID); return(status); } return E_DB_OK; }
/*{ ** Name: psy_reregister - REREGISTER a STAR object. ** ** INTERNAL PSF call format: status = psy_reregister(&psy_cb, &sess_cb); ** ** EXTERNAL call format: status = psy_call(PSY_REREGISTER, &psy_cb, ** &sess_cb); ** ** Description: ** The psy_reregister function will call QEF to REREGISTER a STAR object. ** QED_DDL_INFO block has been already prepared, so there is very little to ** do here. ** ** Inputs: ** psy_cb ** .psy_dmucb ptr to QED_DDL_INFO ** sess_cb Pointer to session control block ** (Can be NULL) ** ** Outputs: ** psy_cb ** .psy_error Filled in if error happens ** .err_code What the error was ** E_PS0000_OK Success ** E_PS0001_USER_ERROR User made a mistake ** E_PS0002_INTERNAL_ERROR Internal inconsistency in PSF ** E_PS0003_INTERRUPTED User interrupt ** E_PS0005_USER_MUST_ABORT User must abort xact ** E_PS0008_RETRY Query should be retried. ** Returns: ** E_DB_OK Function completed normally. ** E_DB_WARN Function completed with warning(s) ** E_DB_ERROR Function failed; non-catastrophic error ** E_DB_FATAL Function failed; catastrophic error ** Exceptions: ** none ** ** Side Effects: ** STAR object will be dropped and recreated with the SAME object id. ** RDF cache entry for this object will be destroyed. ** History: ** 04-apr-89 (andre) ** written ** 15-jun-92 (barbara) ** All psy functions called from psy_call pass the same parameters. ** Add session control block to fit in with this scheme. ** 03-aug-92 (barbara) ** Invalidate registered object from RDF cache. ** 07-dec-92 (andre) ** address of psy_dmucb (which is overloaded with the address of a ** QED_DDL_INFO) will be stored in QEU_CB.qeu_ddl_info instead ** of overloading qeu_qso. ** 10-aug-93 (andre) ** fixed the cause of a compiler warning */ DB_STATUS psy_reregister( PSY_CB *psy_cb, PSS_SESBLK *sess_cb, QEU_CB *qeu_cb) { char *ddb_obj_name; i4 err_code; RDF_CB rdf_cb; RDR_RB *rdf_rb = &rdf_cb.rdf_rb; DB_STATUS status; qeu_cb->qeu_d_cb = (PTR) NULL; qeu_cb->qeu_ddl_info = psy_cb->psy_dmucb; qeu_cb->qeu_d_op = QED_RLINK; status = qef_call(QEU_DBU, ( PTR ) qeu_cb); if (DB_FAILURE_MACRO(status)) { switch (qeu_cb->error.err_code) { /* object unknown */ case E_QE0031_NONEXISTENT_TABLE: { ddb_obj_name = ((QED_DDL_INFO *) psy_cb->psy_dmucb)->qed_d1_obj_name; (VOID) psf_error(E_PS0903_TAB_NOTFOUND, 0L, PSF_USERERR, &err_code, &psy_cb->psy_error,1, psf_trmwhite(sizeof(DD_OBJ_NAME), ddb_obj_name), ddb_obj_name); break; } /* interrupt */ case E_QE0022_QUERY_ABORTED: { (VOID) psf_error(E_PS0003_INTERRUPTED, 0L, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* should be retried */ case E_QE0023_INVALID_QUERY: { psy_cb->psy_error.err_code = E_PS0008_RETRY; break; } /* user has some other locks on the object */ case E_QE0051_TABLE_ACCESS_CONFLICT: { (VOID) psf_error(E_PS0D21_QEF_ERROR, 0L, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* resource related */ case E_QE000D_NO_MEMORY_LEFT: case E_QE000E_ACTIVE_COUNT_EXCEEDED: case E_QE000F_OUT_OF_OTHER_RESOURCES: case E_QE001E_NO_MEM: { (VOID) psf_error(E_PS0D23_QEF_ERROR, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* lock timer */ case E_QE0035_LOCK_RESOURCE_BUSY: case E_QE0036_LOCK_TIMER_EXPIRED: { (VOID) psf_error(4702L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* resource quota */ case E_QE0052_RESOURCE_QUOTA_EXCEED: case E_QE0067_DB_OPEN_QUOTA_EXCEEDED: case E_QE0068_DB_QUOTA_EXCEEDED: case E_QE006B_SESSION_QUOTA_EXCEEDED: { (VOID) psf_error(4707L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* log full */ case E_QE0024_TRANSACTION_ABORTED: { (VOID) psf_error(4706L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* deadlock */ case E_QE002A_DEADLOCK: { (VOID) psf_error(4700L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* lock quota */ case E_QE0034_LOCK_QUOTA_EXCEEDED: { (VOID) psf_error(4705L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } /* inconsistent database */ case E_QE0099_DB_INCONSISTENT: { (VOID) psf_error(38L, qeu_cb->error.err_code, PSF_USERERR, &err_code, &psy_cb->psy_error,0); break; } case E_QE0025_USER_ERROR: { psy_cb->psy_error.err_code = E_PS0001_USER_ERROR; break; } default: { (VOID) psf_error(E_PS0D20_QEF_ERROR, qeu_cb->error.err_code, PSF_INTERR, &err_code, &psy_cb->psy_error,0); } } return (status); } /* Invalidate registered object from RDF cache */ { QED_DDL_INFO *ddl_info = (QED_DDL_INFO *)psy_cb->psy_dmucb; pst_rdfcb_init(&rdf_cb, sess_cb); STRUCT_ASSIGN_MACRO(ddl_info->qed_d7_obj_id, rdf_rb->rdr_tabid); status = rdf_call(RDF_INVALIDATE, (PTR) &rdf_cb); if (DB_FAILURE_MACRO(status)) { (VOID) psf_rdf_error(RDF_INVALIDATE, &rdf_cb.rdf_error, &psy_cb->psy_error); } } return (status); }
/*{ ** Name: scs_get_dbpriv - obtain applicable database privileges from iidbpriv ** ** Description: ** This routine reads privilege descriptors for the database/grantee ** from the iidbpriv catalog, and calls scs_calc_dbpriv to factor ** each tuple into the session's database privileges. ** ** Inputs: ** scb address of session control block ** qeu address of QEU request block ** inpriv the dbprivs to be factored ** Outputs: ** outpriv output privileges ** ** Returns: ** E_DB_OK Privileges were read/factored ** E_DB_INFO No privileges found/factored ** E_DB_ERROR Error reading iidbpriv ** Exceptions: ** none ** ** Side Effects: ** none ** ** History: ** 20-apr-89 (ralph) ** Written for GRANT Enhancements, Phase 2 ** 2-Jul-1993 (daveb) ** prototyped. ** 22-oct-94 (robf) ** Added idle/connect/priority limits ** 18-mar-94 (robf) ** Reworked to write to outpriv rather than SCB ** [@history_template@]... */ DB_STATUS scs_get_dbpriv(SCD_SCB *scb , QEU_CB *qeu , DB_PRIVILEGES *inpriv, SCS_DBPRIV *outpriv) { DB_STATUS status; bool found=FALSE; SCS_DBPRIV cvtdbpriv; u_i4 control; /* Control is the mask of settable privileges */ control = ~outpriv->ctl_dbpriv; /* "Prime the pump" */ qeu->qeu_getnext = QEU_REPO; qeu->qeu_mask = 0; status = qef_call(QEU_GET, qeu); qeu->qeu_getnext = QEU_NOREPO; /* Process each applicable dbpriv record */ for (;status == E_DB_OK;) { /* Reset control flags to those not previously specified */ inpriv->dbpr_control &= control; /* Convert value to an SCS_DBPRIV */ scs_cvt_dbpr_tuple(scb, inpriv, &cvtdbpriv); /* Invoke scs_calc_dbpriv to factor in these privileges */ (VOID)scs_merge_dbpriv(scb, &cvtdbpriv, outpriv); found=TRUE; /* Get the next applicable privilege descriptor */ status = qef_call(QEU_GET, qeu); } /* Check for errors */ if (qeu->error.err_code != E_QE0015_NO_MORE_ROWS) { sc0e_0_put(E_US1888_IIDBPRIV, 0); sc0e_0_put(qeu->error.err_code, 0); qeu->error.err_code = E_US1888_IIDBPRIV; status = (status > E_DB_ERROR) ? status : E_DB_ERROR; } else if(!found) status = E_DB_INFO; else status = E_DB_OK; /* Return to caller */ return(status); }