Beispiel #1
0
/*{
** Name: psy_qminit	- Allocate and initialize the PSY_CB
**
** Description:
**      This function allocates and initialzes the qrymod control
**	block, PSY_CB.  It is called by the grammar.
**
** Inputs:
**	sess_cb				Current session control block
**	psq_cb
**	    .err_blk			Filled in if an error happens
**	mstream				memory stream to use for allocating a
**					PSY_CB
**
** Outputs:
**	sess_cb
**	    .pss_object			Points to allocated psy_cb
**	Returns:
**	    E_DB_OK			Success
**	    Other			Return code from called functions
**	Exceptions:
**	    none
**
** Side Effects:
**	    Allocates memory
**
** History:
**      22-jul-89 (ralph)
**          Written.
**	08-aug-90 (ralph)
**	    Initialize new psy_cb fields.
**	14-jul-92 (andre)
**	    init PSY_CB.psy_flags
**	14-jul-92 (andre)
**	    added mstream to the function's interface which will enable it to no
**	    longer assume that PSY_CB must be allocated from any given stream.
**	20-jul-92 (andre)
**	    added initialization for psy_xcolq
**	20-jul-92 (andre)
**	    iprocessing DROP PROCEDURE (psq_cb->psq_mode == PSQ_DRODBP), memory
**	    stream has already been opened, so don't do it here
**	21-jul-92 (andre)
**	    removed initialization for psy_xcolq;
**
**	    replaced code initializing various fields to 0 with a call to MEfill
**	    to fill a newly allocated PSY_CB with 0's
**	06-dec-92 (andre)
**	    Added code to initialize psy_u_colq and psy_r_colq
**	10-jul-93 (andre)
**	    cast QUinit()'s arg to (QUEUE *) to agree with the prototype
**	    declaration
**	 7-jan-94 (swm)
**	    Bug #58635
**	    Added PTR cast for qsf_owner which has changed type to PTR.
**	28-apr-94 (andre)
**	    (part of fix for bug 62890)
**	    if the statement was generated internally 
**	    (psq_cb->psq_info->pst_execflags & PST_SYSTEM_GENERATED), set 
**	    PSY_SYSTEM_GENEARTED in psy_cb->psy_flags.
*/
DB_STATUS
psy_qminit(
	PSS_SESBLK	    *sess_cb,
	PSQ_CB		    *psq_cb,
	PSF_MSTREAM	    *mstream)
{
    DB_STATUS	    status;
    PSY_CB	    *psy_cb;

    /*
    ** open the memory stream unless we are processing DROP PROCEDURE, in which
    ** case it has already been opened
    */
    if (psq_cb->psq_mode != PSQ_DRODBP)
    {
	/* Allocate the PSY_CB statement */
	status = psf_mopen(sess_cb, QSO_QP_OBJ, mstream, &psq_cb->psq_error);
	if (status != E_DB_OK)
	    return (status);
    }

    status = psf_malloc(sess_cb, mstream, sizeof(PSY_CB), &sess_cb->pss_object,
	&psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);

    status = psf_mroot(sess_cb, mstream, sess_cb->pss_object, &psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);

    psy_cb = (PSY_CB *) sess_cb->pss_object;

    MEfill(sizeof(PSY_CB), (u_char) 0, (PTR) psy_cb);

    /* Fill in control block header */
    psy_cb->psy_length	 = sizeof(PSY_CB);
    psy_cb->psy_type	 = PSYCB_CB;
    psy_cb->psy_owner	 = (PTR)DB_PSF_ID;
    psy_cb->psy_ascii_id = PSYCB_ASCII_ID;

    (VOID) QUinit((QUEUE *) &psy_cb->psy_usrq);	/* No users */
    (VOID) QUinit((QUEUE *) &psy_cb->psy_tblq);	/* No tables */
    (VOID) QUinit((QUEUE *) &psy_cb->psy_colq);	/* No columns */
    (VOID) QUinit((QUEUE *) &psy_cb->psy_u_colq);
    (VOID) QUinit((QUEUE *) &psy_cb->psy_r_colq);

    /*
    ** remember whether the statement was generated internally
    */
    if (   psq_cb->psq_info 
	&& psq_cb->psq_info->pst_execflags & PST_SYSTEM_GENERATED)
    {
	psy_cb->psy_flags |= PSY_SYSTEM_GENERATED;
    }

    return(E_DB_OK);
}
Beispiel #2
0
/*{
** Name: psy_txtalloc	- Allocate a new text block
**
** Description:
**      This function allocates a new text block in a memory stream,
**	fills it in, and returns a pointer to it.
**
** Inputs:
**      mstream                         Pointer to memory stream
**	newblock			Place to put pointer to new block
**	err_blk				Filled in if error happens
**
** Outputs:
**      newblock                        Filled in with pointer to new block
**	err_blk				Filled in if an error happened
**	Returns:
**	    E_DB_OK			Success
**	    E_DB_ERROR			Failure
**	Exceptions:
**	    none
**
** Side Effects:
**	    Allocates memory
**
** History:
**      15-jul-86 (jeff)
**          written
*/
DB_STATUS
psy_txtalloc(
	PSF_MSTREAM        *mstream,
	PSY_QTEXT	   **newblock,
	DB_ERROR	   *err_blk)
{
    DB_STATUS           status;
    PSS_SESBLK	   	*sess_cb;

    sess_cb = psf_sesscb();

    /* Allocate the block */
    status = psf_malloc(sess_cb, mstream, sizeof(PSY_QTEXT), (PTR *) newblock, err_blk);
    if (DB_FAILURE_MACRO(status))
	return (status);

    /* Fill in the block */
    (*newblock)->psy_qnext = (PSY_QTEXT *) NULL;
    (*newblock)->psy_qcount = 0;

    return (E_DB_OK);
}
Beispiel #3
0
DB_STATUS
pst_ruledup(
	PSS_SESBLK  	*sess_cb,
	PSF_MSTREAM     *mstream,
	i4		filter,
	char		*col_mask,
	PST_STATEMENT	*stmt_tree,
	PST_STATEMENT	**stmt_dup,
	DB_ERROR	*err_blk)
{
    PST_STATEMENT	*curs;		/* Current stmt to walk through list */
    PST_STATEMENT	*ifs;		/* IF statement */
    PST_STATEMENT	*cps;		/* CP statement */
    PST_STATEMENT	*prev_if;	/* Previous IF and CP statements to  */
    PST_STATEMENT	*prev_cp;	/*     patch dangling pointers       */
    PST_STATEMENT	*cur_rule;	/* PTR to CP node or IF-CP node pair */
    PST_STATEMENT	*result;	/* Return value - start of list */
    PSC_RULE_TYPE	*rtype;		/* Filter rule type */
    DB_COLUMN_BITMAP	tst_mask;       /* test mask for update columns */
    DB_STATUS           status;
    PSS_DUPRB		dup_rb;
    i4		err_code;

    *stmt_dup = result = NULL;
    if ((curs = stmt_tree) == NULL)	/* Nothing doing */
	return (E_DB_OK);

    prev_if = NULL;
    prev_cp = NULL;

    /* initialize fields in dup_rb */
    dup_rb.pss_op_mask = 0;
    dup_rb.pss_num_joins = PST_NOJOIN;
    dup_rb.pss_tree_info = (i4 *) NULL;
    dup_rb.pss_mstream = mstream;
    dup_rb.pss_err_blk = err_blk;
    
    while (curs != NULL)
    {
	/* 
	** Filter out current rule if not applicable.  Check statement type of
	** caller and rule, and column mask.
	*/
	if (filter != 0)
	{
	    if ((rtype = (PSC_RULE_TYPE *)curs->pst_opf) == NULL)
	    {
		psf_error(E_PS0C06_BAD_STMT, 0L, PSF_INTERR, 
			  &err_code, err_blk, 1,
			  sizeof("PSC_RULE_TYPE.pst_opf")-1,
			  "PSC_RULE_TYPE.pst_opf");
		return (E_DB_ERROR);
	    }

	    /* copy the bitmap of the rule to an overwriteable test mask,
	    ** and test that against the bitmap of columns being updated
	    */
	    MEcopy((PTR) &rtype->psr_columns,
		   sizeof(DB_COLUMN_BITMAP), (PTR) &tst_mask);
	    BTand((i4) DB_COL_BITS, 
		  (char *) col_mask, (char *) tst_mask.db_domset);

	    /* Check statement type of caller and rule,
	    ** and check result of column bitmap test. 
	    */
	    if (   ((rtype->psr_statement & filter) == 0)
		|| (BTcount((char *) tst_mask.db_domset, DB_COL_BITS) == 0)
	       )
	    {
		curs = curs->pst_next;		/* Skip this one */
		continue;
	    }
	}
	ifs = cps = NULL;		/* Current ones start out nulled */

	/* If found IF, allocate node, patch pointers & continue with CP node */
	if (curs->pst_type == PST_IF_TYPE)
	{
	    status = psf_malloc(sess_cb, mstream, sizeof(*ifs), (PTR*)&ifs, err_blk);

	    if (status != E_DB_OK)
		return (status);
		
	    STRUCT_ASSIGN_MACRO(*curs, *ifs);

	    if (filter != 0)		/* Detach for safety when filtering */
		ifs->pst_opf = NULL;

	    /* Patch/copy IF condition pointer and confirm it exists*/
	    dup_rb.pss_tree = curs->pst_specific.pst_if.pst_condition;
	    dup_rb.pss_dup  = &ifs->pst_specific.pst_if.pst_condition;
	    status = pst_treedup(sess_cb, &dup_rb);

	    if (status != E_DB_OK)
		return (status);
		
	    if (ifs->pst_specific.pst_if.pst_condition == NULL)
	    {
		psf_error(E_PS0C06_BAD_STMT, 0L, PSF_INTERR, 
			  &err_code, err_blk, 1,
			  sizeof("PST_IF.pst_condition") - 1,
			  "PST_IF.pst_condition");
		return (E_DB_ERROR);
	    }
	    /* True and False links done later */

	    curs = ifs->pst_link;	/* Better be a CP statement node */
	} /* If found an IF node */

	if (curs->pst_type != PST_CP_TYPE)
	{
	    psf_error(E_PS0C06_BAD_STMT, 0L, PSF_INTERR, 
		      &err_code, err_blk, 1,
		      sizeof("PST_CP") - 1, "PST_CP");
	    return (E_DB_ERROR);
	}

	/* Allocate and initialize CP node */
	status = psf_malloc(sess_cb, mstream, sizeof(*cps), (PTR *)&cps, err_blk);

	if (status != E_DB_OK)
	    return (status);
	    
	STRUCT_ASSIGN_MACRO(*curs, *cps);

	if (filter != 0)		/* Detach for safety when filtering */
	    cps->pst_opf = NULL;

	/* If there are any arguments patch/copy arguments list pointer */
	if (curs->pst_specific.pst_callproc.pst_arglist != NULL)
	{
	    dup_rb.pss_tree = curs->pst_specific.pst_callproc.pst_arglist;
	    dup_rb.pss_dup  = &cps->pst_specific.pst_callproc.pst_arglist;
	    status = pst_treedup(sess_cb, &dup_rb);

	    if (status != E_DB_OK)
		return (status);
	}

	/* Adjust pointers of [IF node and] CP node */
	if (ifs != NULL)
	{
	    cur_rule = ifs;			/* Rule pair is IF->CP */
	    ifs->pst_link = cps;
	    ifs->pst_specific.pst_if.pst_true = cps;
	}
	else
	{
	    cur_rule = cps;			/* Rule is just CP */
	}

	if (result == NULL)			/* 1st rule - no patch needed */
	{
	    result = cur_rule;		
	}
	else       /* Patch dangling pointers of previous [IF node &] CP node */
	{
	    if (prev_if != NULL)
	    {
		prev_if->pst_next = cur_rule;
		prev_if->pst_specific.pst_if.pst_false = cur_rule;
	    }
	    prev_cp->pst_next = cur_rule;
	    prev_cp->pst_link = cur_rule;
	}

	/* Move on to next statement */
	prev_if = ifs;
	prev_cp = cps;
	curs = curs->pst_next;
    } /* While there are more statements */

    /* Clear dangling pointers of last [IF node and] CP node */
    if (prev_if != NULL)
    {
	prev_if->pst_next = NULL;
	prev_if->pst_specific.pst_if.pst_false = NULL;
    }
    if (prev_cp != NULL)	/* Could be null if all were filtered out */
    {
	prev_cp->pst_next = NULL;
	prev_cp->pst_link = NULL;
    }
    *stmt_dup = result;
    return (E_DB_OK);
} /* pst_ruledup */
Beispiel #4
0
/*
** Name: psq_store_text - store query text in a contiguous block of QSF memory
**
** Description:
**	Copy contents of a query text chain (prepended, if necessary with RANGE
**	statements) into a contiguous block of QSF memory.  Caller may specify
**	that the text be stored in DB_TEXT_STRING format by setting
**	return_db_text_string to TRUE; otherwise the function will return a i4
**	followed by query text.
**
** Input:
**	rngtab			if non-NULL, range statements will be
**				generated for all entries of the range table
**				that are active (pss_used && pss_rgno >= 0);
**				should be non-NULL only for QUEL queries
**      header			Pointer to chain header
**	mstream			Pointer to opened memory stream
**	return_db_text_string	if TRUE, function will store text in
**				DB_TEXT_STRING format; otherwise it will store
**				it a a i4  (length) followed by text
**
** Output:
**	result			query text in specified format
**	err_blk			Filled in if an error happens
**
** Side efects:
**	allocates memory
**
** Returns:
**	E_DB_{OK,ERROR}
**
** History:
**	09-jan-93 (andre)
**	    written
**	29-jul-2001 (toumi01)
**	    problem found doing i64_aix port:
**	    (u_char *)'\n' should be (uchar)'\n'
**	    (u_char *)'\0' should be (uchar)'\0'
**      26-Oct-2009 (coomi01) b122714
**          Move psq_store_text() declarator to pshparse.h and make it public here.
**	24-Jun-2010 (kschendel) b123775
**	    Correct a call to trim-whitespace.
*/
DB_STATUS
psq_store_text(
	PSS_SESBLK	    *sess_cb,
	PSS_USRRANGE	    *rngtab,
	PTR		    header,
	PSF_MSTREAM	    *mstream,
	PTR		    *result,
	bool		    return_db_text_string,
	DB_ERROR	    *err_blk)
{
    DB_STATUS		status;
    i4			i;
    PSQ_THEAD		*hp = (PSQ_THEAD *) header;
    i4			size = hp->psq_tsize;
    PSQ_TEXT		*tp;
    PSS_RNGTAB		*rngvar;
    u_char		*out;
    
    if (rngtab)
    {
	/*
	** allocate enough space for range statements. each range statement
	** looks like range of 'rngname' is 'tabname'\n.
	** Thus, max space is 14+2*DB_MAX_NAME.
	*/
	for (i = 0, rngvar = rngtab->pss_rngtab; i < PST_NUMVARS; i++, rngvar++)
	{
	    /* Only look at range vars that are being used */
	    if (rngvar->pss_used && rngvar->pss_rgno >= 0)
	    {
		size += (  14   /* "range of  is \n" */
			 + psf_trmwhite(DB_TAB_MAXNAME, rngvar->pss_rgname)
			 + psf_trmwhite(sizeof(DB_TAB_NAME),
			       (char *) &rngvar->pss_tabname));
	    }
	}
    }
    
    if (return_db_text_string)
    {
	DB_TEXT_STRING	    *str;

	status = psf_malloc(sess_cb, mstream, size + sizeof(*str) - sizeof(u_char),
	    result, err_blk);
	if (status != E_DB_OK)
	    return (status);

	str = (DB_TEXT_STRING *) *result;

	/*
	** store the total length of query text 
	*/
	str->db_t_count = size;

	out = str->db_t_text;

    }
    else
    {
	/* Allocate a piece large enough for all the text + a i4  (count) */
	status = psf_malloc(sess_cb, mstream, size + sizeof(i4), result, err_blk);
	if (status != E_DB_OK)
	    return (status);

	out = (u_char *) *result;
	
	/* Copy the length into the buffer */
	MEcopy((char *) &size, sizeof(size), (char *) out);

	out += sizeof(size);
    }
    
    /* Copy the pieces into the buffer; first put the range statements */
    if (rngtab)
    {
	for (i = 0, rngvar = rngtab->pss_rngtab; i < PST_NUMVARS; i++, rngvar++)
	{
	    /* Only look at range vars that are being used */
	    if (rngvar->pss_used && rngvar->pss_rgno >= 0)
	    {
		i4 plen;

		STncpy( (char *)out, "range of ", 9);
		out += 9;

		/* add in range name */
		plen = psf_trmwhite(DB_TAB_MAXNAME, rngvar->pss_rgname);
		STncpy( (char *)out, rngvar->pss_rgname, plen);
		out += plen;

		STncpy( (char *)out, " is ", 4);
		out += 4;

		plen = psf_trmwhite(DB_TAB_MAXNAME, rngvar->pss_tabname.db_tab_name);
		STncpy( (char *)out, (char *)&rngvar->pss_tabname, plen);
		out += plen;

		*out = (u_char)'\n';
		out++;
		*out = (u_char)'\0';
	    }
	}
    }

    for (tp = hp->psq_first; tp != (PSQ_TEXT *) NULL; tp = tp->psq_next)
    {
	MEcopy((char *) tp->psq_tval, tp->psq_psize, (char *) out);
	out += tp->psq_psize;
    }

    return(E_DB_OK);
}
Beispiel #5
0
/*
** Name psl_lm1_setlockstmnt() - perform semantic action for SETLOCKSTMNT
**			         production
**
** Description:
**	perform semantic action for SETLOCKSTMNT production in QUEL and SQL
**	grammars
**
** Input:
**	sess_cb		    PSF session CB
**	    pss_distrib	    DB_3_DDB_SESS if distributed thread
**	    pss_ostream	    stream to be opened for memory allocation
**	    pss_stmt_flags  PSS_SET_LOCKMODE_SESS if SET LOCKMODE SESSION
**	psq_cb		    PSF request CB
**
** Output:
**	sess_cb
**	    pss_ostream	    stream has been opened for memory allocation
**	    pss_object	    point to the root of a new QSF object
**			    (of type (DMC_CB *) or (QEF_RCB *)).
**	psq_cb
**	    psq_mode	    set to PSQ_SLOCKMODE
**	    psq_error	    filled in if an error occurred
**
** Returns:
**	E_DB_{OK, ERROR, SEVERE}
**
** Side effects:
**	Opens a memory stream and allocates memory
**
**  History:
**	07-mar-91 (andre)
**	    plagiarized from SETLOCKSTMNT production
**	17-apr-92 (barbara)
**	    Updated for Sybil.  Distributed thread allocates QEF_RCB and
**	    calls QEF directly.
**	07-oct-93 (swm)
**	    Bug #56437
**	    added PTR cast in assignment to dmc_cb->dmc_id.
**	09-oct-93 (swm)
**	    Bug #56437
**	    Put pss_sessid into new dmc_session_id rather than dmc_id.
**	26-Feb-2001 (jenjo02)
**	    Set session_id in QEF_RCB;
**	11-Jun-2010 (kiria01) b123908
**	    Initialise pointers after psf_mopen would have invalidated any
**	    prior content.
*/
DB_STATUS
psl_lm1_setlockstmnt(
	PSS_SESBLK	*sess_cb,
	PSQ_CB		*psq_cb)
{
    DB_STATUS		status;
    i4		err_code;
    DMC_CB		*dmc_cb;
    DB_ERROR		err_blk;
    DB_STATUS	        tempstat;

    psq_cb->psq_mode = PSQ_SLOCKMODE;

    /* Verify the user has LOCKMODE permission */

    status = psy_ckdbpr(psq_cb, (u_i4) DBPR_LOCKMODE);
    if (DB_FAILURE_MACRO(status))
    {
	(VOID) psf_error(6247L, 0L, PSF_USERERR, &err_code,
	    &psq_cb->psq_error, 0);
	/*
	** Audit failed  set lockmode
	*/
	if ( Psf_srvblk->psf_capabilities & PSF_C_C2SECURE )
	{
	    (VOID)psy_secaudit(
		    FALSE,
		    sess_cb,
		    "LOCKMODE",
		    (DB_OWN_NAME *)0,
		    8,
		    SXF_E_RESOURCE,
		    I_SX2741_SET_LOCKMODE,
		    SXF_A_FAIL|SXF_A_LIMIT,
		    &err_blk);
	}
	return(status);
    }

    /* Create control block for DMC_ALTER or QEF_CALL for set lockmode */
    status = psf_mopen(sess_cb, QSO_QP_OBJ, &sess_cb->pss_ostream, &psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);
    sess_cb->pss_stk_freelist = NULL;

    if (sess_cb->pss_distrib & DB_3_DDB_SESS)
    {
	/* Distributed thread calls QEF directly */
	QEF_RCB	*qef_rcb;

	status = psf_malloc(sess_cb, &sess_cb->pss_ostream, sizeof(QEF_RCB),
	    &sess_cb->pss_object, &psq_cb->psq_error);
	if (status != E_DB_OK)
	    return (status);

	status = psf_mroot(sess_cb, &sess_cb->pss_ostream, sess_cb->pss_object,
			   &psq_cb->psq_error);
	if (status != E_DB_OK)
	    return (status);

	/* Fill in the QEF control block */
	qef_rcb = (QEF_RCB *) sess_cb->pss_object;
	qef_rcb->qef_length = sizeof(QEF_RCB);
	qef_rcb->qef_type = QEFRCB_CB;
	qef_rcb->qef_owner = (PTR)DB_PSF_ID;
	qef_rcb->qef_ascii_id = QEFRCB_ASCII_ID;
	qef_rcb->qef_modifier = QEF_MSTRAN;
	qef_rcb->qef_flag = 0;
	qef_rcb->qef_cb = (QEF_CB *) NULL;
	qef_rcb->qef_sess_id = sess_cb->pss_sessid;
	return (E_DB_OK);
    }

    status = psf_malloc(sess_cb, &sess_cb->pss_ostream, sizeof(DMC_CB), (PTR *) &dmc_cb,
	&psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);

    status = psf_mroot(sess_cb, &sess_cb->pss_ostream, (PTR) dmc_cb, &psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);

    sess_cb->pss_object		= (PTR) dmc_cb;
    dmc_cb->type		= DMC_CONTROL_CB;
    dmc_cb->length		= sizeof (DMC_CB);
    dmc_cb->dmc_op_type		= DMC_SESSION_OP;
    dmc_cb->dmc_session_id	= (PTR)sess_cb->pss_sessid;
    dmc_cb->dmc_flags_mask	= DMC_SETLOCKMODE;
    dmc_cb->dmc_db_id		= sess_cb->pss_dbid;
    dmc_cb->dmc_db_access_mode  =
    dmc_cb->dmc_lock_mode	= 0;

    /* need to allocate characteristics array with MAX_LOCKMODE_CHARS entries */
    status = psf_malloc(sess_cb, &sess_cb->pss_ostream,
	sizeof(DMC_CHAR_ENTRY) * MAX_LOCKMODE_CHARS,
	(PTR *) &dmc_cb->dmc_char_array.data_address, &psq_cb->psq_error);
    if (status != E_DB_OK)
	return (status);

    dmc_cb->dmc_char_array.data_in_size = 0;

    /*
    ** Audit allowed to issue lockmode
    */
    if ( Psf_srvblk->psf_capabilities & PSF_C_C2SECURE )
    {
	(VOID)psy_secaudit(
	    FALSE,
	    sess_cb,
	    "LOCKMODE",
	    (DB_OWN_NAME *)0,
	    8,
	    SXF_E_RESOURCE,
	    I_SX2741_SET_LOCKMODE,
	    SXF_A_SUCCESS|SXF_A_LIMIT,
	    &err_blk);
    }

    return(E_DB_OK);
}