예제 #1
0
파일: psllkmd.c 프로젝트: saqibjamil/Ingres
/*
** 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);
}
예제 #2
0
/*
** 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;
}
예제 #3
0
/*{
** 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);
}
예제 #4
0
/*{
** 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);
}