Beispiel #1
0
DB_STATUS
qee_p1_dsh_gen(
	QEF_RCB		*v_qer_p,
	QEE_DSH		*i_dsh_p)
{
    DB_STATUS	    status = E_DB_OK;
    QEF_QP_CB	    *qp_p = i_dsh_p->dsh_qp_ptr;    /* debugging aid */
    QEE_DDB_CB	    *dde_p = i_dsh_p->dsh_ddb_cb;
    char	    cur_name[DB_CURSOR_MAXNAME + 1];
    char	    *cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4		    cbufsize = v_qer_p->qef_cb->qef_trsize;


    qed_u0_trimtail(i_dsh_p->dsh_qp_id.db_cur_name, DB_CURSOR_MAXNAME, cur_name);

    STprintf(cbuf, 
	"%s %p: ...    query id: %x %x %s\n",
	IIQE_61_qefsess,
	(PTR) v_qer_p->qef_cb,
	i_dsh_p->dsh_qp_id.db_cursor_id[0],
	i_dsh_p->dsh_qp_id.db_cursor_id[1],
	cur_name);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    if (i_dsh_p->dsh_qp_status & DSH_QP_LOCKED)
    {
 	STprintf(cbuf, 
	    "%s %p: ...     query plan LOCKED by this session\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (i_dsh_p->dsh_qp_status & DSH_QP_OBSOLETE)
    {
	STprintf(cbuf, 
	    "%s %p: ...     query plan is OBSOLETE; to be destroyed\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (i_dsh_p->dsh_qp_status & DSH_DEFERRED_CURSOR)
    {
	STprintf(cbuf, 
	    "%s %p: ...     query plan contains a DEFERRED cursor\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (i_dsh_p->dsh_positioned)
    {
	STprintf(cbuf, 
	    "%s %p: ...     cursor is positioned\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    return(E_DB_OK);
}
Beispiel #2
0
DB_STATUS
qee_p4_ldb_qid(
	QEF_RCB		*v_qer_p,
	QEE_DSH         *i_dsh_p)
{
/*
    DB_STATUS	    status = E_DB_OK;
    QES_DDB_SES	    *dds_p = & v_qer_p->qef_cb->qef_c2_ddb_ses;
    QEF_DDB_REQ     *ddr_p = & v_qer_p->qef_r3_ddb_req;
*/
    QEE_DDB_CB      *qee_p = i_dsh_p->dsh_ddb_cb;
    DB_CURSOR_ID    *ldb_qid_p = & qee_p->qee_d5_local_qid;
    char	    cur_name[DB_CURSOR_MAXNAME + 1];
    char	    *cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4		    cbufsize = v_qer_p->qef_cb->qef_trsize;


    STprintf(cbuf, 
	"%s %p: ...the LDB query id:\n",
        IIQE_61_qefsess,
        (PTR) v_qer_p->qef_cb);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    STprintf(cbuf, 
	"%s %p: ...   1) DB_CURSOR_ID[0] %x,\n",
	IIQE_61_qefsess,
	(PTR) v_qer_p->qef_cb,
	ldb_qid_p->db_cursor_id[0]);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    STprintf(cbuf, 
	"%s %p: ...   2) DB_CURSOR_ID[1] %x,\n",
	IIQE_61_qefsess,
	(PTR) v_qer_p->qef_cb,
	ldb_qid_p->db_cursor_id[1]);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    qed_u0_trimtail(ldb_qid_p->db_cur_name, DB_CURSOR_MAXNAME, cur_name);

    STprintf(cbuf, 
	"%s %p: ...   3) DB_CUR_NAME     %s\n",
	IIQE_61_qefsess,
	(PTR) v_qer_p->qef_cb,
	cur_name);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    return(E_DB_OK);
}
Beispiel #3
0
DB_STATUS
qee_p0_prt_dsh(
	QEF_RCB		*v_qer_p,
	QEE_DSH		*i_dsh_p)
{
    DB_STATUS	    status = E_DB_OK;
    QEF_CB	    *qecb_p = v_qer_p->qef_cb;
    char	    *cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4		    cbufsize = v_qer_p->qef_cb->qef_trsize;


    if (TRUE)
	return(E_DB_OK);

    STprintf(cbuf, 
	"%s %p: ...1.1) Generic DSH information\n",
	IIQE_61_qefsess,
	(PTR) v_qer_p->qef_cb);
    qec_tprintf(v_qer_p, cbufsize, cbuf);

    status = qee_p1_dsh_gen(v_qer_p, i_dsh_p);
    if (status)
	return(status);

    if (qecb_p->qef_c1_distrib & DB_3_DDB_SESS) 
    {
	STprintf(cbuf, 
	    "%s %p: ...1.2) DDB-specific DSH information\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);

	status = qee_p2_dsh_ddb(v_qer_p, i_dsh_p);
    }
    return(status);
}
Beispiel #4
0
/*
** Name: QEN_PRINT_ROW	- This routine prints the current row for a given 
**								    QEN_NODE
**
** Description:
**      This routine prints out the current row for the given QEN_NODE. 
**      This is done with the help of ADF, who converts data into a 
**      printable form, similiar to what the terminal monitor needs to do. 
**
**	FIXME this really belongs in qenutl since it applies to any node,
**	not just fsm-joins.
**
** Inputs:
**	node -
**	    The qen_node that refers to the row.
**	qef_rcb -
**	    The request control block that we get most of our query common 
**	    info from, like cbs, the dsh, dsh rows, etc.
**
** Outputs:
**
**	Returns:
**	    DB_STATUS
**	Exceptions:
**	    none
**
** Side Effects:
**	    causes a row to be printed to the FE (via SCC_TRACE).
**
** History:
**      17-may-89 (eric)
**          created
**	6-aug-04 (inkdo01)
**	    Drop increment of node_rcount - it's already incremented in the 
**	    node handlers and this simply doubles its value.
**	13-Dec-2005 (kschendel)
**	    Can count on qen-ade-cx now.
**      11-Mar-2010 (hanal04) Bug 123415 
**          Make sure QE99 and OP173 do not interleave output with
**          using parallel query.
**	12-May-2010 (kschendel) Bug 123720
**	    Above doesn't quite go far enough, mutex the buffer.
**          Take qef_trsem for valid parallel-query output.
*/
DB_STATUS
qen_print_row(
QEN_NODE	*node,
QEF_RCB		*qef_rcb,
QEE_DSH		*dsh )
{
    QEN_STATUS	    *qen_status = dsh->dsh_xaddrs[node->qen_num]->qex_status;
    QEN_ADF	    *qen_adf;
    DB_STATUS	    status = E_DB_OK;
    char	    *cbuf = dsh->dsh_qefcb->qef_trfmt;
    i4		    cbufsize = dsh->dsh_qefcb->qef_trsize;

    qen_adf = node->qen_prow;		/* Checked non-NULL by caller */
    if (qen_status->node_rcount > 0)
    {
	/* process the row print expression */
	status = qen_execute_cx(dsh, dsh->dsh_xaddrs[node->qen_num]->qex_prow);
	if (status != E_DB_OK)
	{
# ifdef	xDEBUG
	    (VOID) qe2_chk_qp(dsh);
# endif
	    return (status);
	
	}

	/* Print in one operation to avoid interleaved output */
	CSp_semaphore(1, &dsh->dsh_qefcb->qef_trsem);
	STprintf(cbuf, "Row %d of node %d\n%s\n\n", 
			    qen_status->node_rcount, node->qen_num,
			    dsh->dsh_row[qen_adf->qen_output]);
        qec_tprintf(qef_rcb, cbufsize, cbuf);
	CSv_semaphore(&dsh->dsh_qefcb->qef_trsem);
    }			
    return(E_DB_OK);
}
Beispiel #5
0
DB_STATUS
qee_p2_dsh_ddb(
	QEF_RCB		*v_qer_p,
	QEE_DSH		*i_dsh_p)
{
    DB_STATUS	    status = E_DB_OK;
    QEF_CB	    *qecb_p = v_qer_p->qef_cb;
    QEF_QP_CB	    *qp_p = i_dsh_p->dsh_qp_ptr;    /* debugging aid */
    QEQ_DDQ_CB	    *ddq_p = & qp_p->qp_ddq_cb;
    QEE_DDB_CB	    *dde_p = i_dsh_p->dsh_ddb_cb;
    DD_TAB_NAME	    *tmptbl_p = (DD_TAB_NAME *) NULL;
    i4	    *sts_p = (i4 *) NULL;
    i4		    i;
    char	    namebuf[DB_TAB_MAXNAME + 1];
    char	    cur_name[DB_CURSOR_MAXNAME + 1];
    char	    *cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4		    cbufsize = v_qer_p->qef_cb->qef_trsize;


    if (! (qecb_p->qef_c1_distrib & DB_3_DDB_SESS) )
	return(E_DB_OK);    /* NOT a DDB session */

    if (ddq_p->qeq_d3_elt_cnt == 0)
    {
	STprintf(cbuf, 
	    "%s %p: ...     0 temporary tables used by query\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    else
    {
	if (ddq_p->qeq_d3_elt_cnt == 1)
	{
	    STprintf(cbuf, 
		"%s %p: ...     1 temporary table ",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}
	else
	{
	    STprintf(cbuf, 
		"%s %p: ...     %d temporary tables ",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb,
		ddq_p->qeq_d3_elt_cnt);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}
	STprintf(cbuf, "used by query\n");
        qec_tprintf(v_qer_p, cbufsize, cbuf);

	/* print all the temporary table names */

	for (i = 1, tmptbl_p = dde_p->qee_d1_tmp_p,
		    sts_p = dde_p->qee_d2_sts_p;
		i <= ddq_p->qeq_d3_elt_cnt; 
		i++, tmptbl_p++, sts_p++)
	    if (*sts_p & QEE_01M_CREATED)
	    {
		qed_u0_trimtail((char *) tmptbl_p, DB_TAB_MAXNAME, namebuf);
		STprintf(cbuf, 
		    "%s %p: ...     %d) %s\n",
		    IIQE_61_qefsess,
		    (PTR) v_qer_p->qef_cb,
		    i,
		    namebuf);
        	qec_tprintf(v_qer_p, cbufsize, cbuf);
	    }
    }

    if (dde_p->qee_d3_status & QEE_01Q_CSR)
    {
        STprintf(cbuf, 
	    "%s %p: ...     query pertains to a CURSOR\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_02Q_RPT)
    {
        STprintf(cbuf, 
	    "%s %p: ...     this is a REPEAT query\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_03Q_DEF)
    {
        STprintf(cbuf, 
	    "%s %p: ...     query has been DEFINED to the LDB\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_04Q_EOD)
    {
	STprintf(cbuf, 
	    "%s %p: ...     query has NO more retrieved data coming back\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_05Q_CDB)
    {
        STprintf(cbuf, 
"%s %p: ...     retrieval REROUTED thru the CDB, to be committed when done\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_06Q_TDS)
    {
        STprintf(cbuf, 
	    "%s %p: ...     RQF returning a tuple descriptor to SCF\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_07Q_ATT)
    {
        STprintf(cbuf, 
	    "%s %p: ...     tuple descriptor contains attribute names\n",
	    IIQE_61_qefsess,
            (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d4_given_qid.db_cursor_id[0] != 0)
    {
	/* null-terminate name part for printing */

	qed_u0_trimtail( dde_p->qee_d4_given_qid.db_cur_name, DB_CURSOR_MAXNAME,
	    cur_name);

	STprintf(cbuf, 
	    "%s %p: ...     DDB query id: %x %x %s\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    dde_p->qee_d4_given_qid.db_cursor_id[0],
	    dde_p->qee_d4_given_qid.db_cursor_id[1],
	    cur_name);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }

    if (dde_p->qee_d5_local_qid.db_cursor_id[0] != 0)
    {
	/* null-terminate name part for printing */

	qed_u0_trimtail( dde_p->qee_d5_local_qid.db_cur_name, DB_CURSOR_MAXNAME,
	    cur_name);

	STprintf(cbuf, 
	    "%s %p: ...     LDB (sub)query id: %x %x %s\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    dde_p->qee_d5_local_qid.db_cursor_id[0],
	    dde_p->qee_d5_local_qid.db_cursor_id[1],
	    cur_name);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }

    if (dde_p->qee_d6_dynamic_cnt > 0)
    {
	if (dde_p->qee_d6_dynamic_cnt == 1)
	{
	    STprintf(cbuf, 
		"%s %p: ...     1 DB_DATA_VALUE ",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}
	else
	{
	    STprintf(cbuf, 
		"%s %p: ...     %d DB_DATA_VALUEs ",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb,
		dde_p->qee_d6_dynamic_cnt);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}
	STprintf(cbuf, "for query\n");
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    if (dde_p->qee_d3_status & QEE_01Q_CSR
	||
	dde_p->qee_d3_status & QEE_02Q_RPT)
    {
	if (dde_p->qee_d3_status & QEE_01Q_CSR)
	{
	    STprintf(cbuf, 
		"%s %p: ...     LDB for this CURSOR query:\n",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}
	else
	{
	    STprintf(cbuf, 
		"%s %p: ...     LDB for this REPEAT query:\n",
		IIQE_61_qefsess,
		(PTR) v_qer_p->qef_cb);
            qec_tprintf(v_qer_p, cbufsize, cbuf);
	}

	/* print the LDB's information */

	status = qed_w1_prt_ldbdesc(v_qer_p, & dde_p->qee_d11_ldbdesc);
    }

    return(E_DB_OK);
}
Beispiel #6
0
/*{
** Name: QEA_CALLPROC		- call the named procedure
**
** Description:
**	The current execution environment is saved and an
**	environment is created in which to execute the
**	named procedure.
**
**	This procedure is only called when a nested procedure is invoked.
**	This can occur the first time through, or if the procedure is not
**	found (LOAD_QP) or the plan was deemed invalid (INVALID_QUERY) then
**	the procedure is re-entered in this routine.
**
**	If rules are turned off (QEF_T_NORULES) then this procedure returns
**	immediately.
**
** Inputs:
**	action			Callproc action header
**      qef_rcb
**	call_dsh		DSH doing the callproc
**	function		unused
**	state			unused
**
** Outputs:
**      call_dsh
**	    .error.err_code	one of the following
**				E_QE0119_LOAD_QP - Load a procedure QP
**				E_QE0125_RULES_INHIBIT - Rules are turned off.
**				E_QE0000_OK
**	Returns:
**	    E_DB_{OK,WARN,ERROR,FATAL}
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	20-apr-89 (paul)
**	    Moved from qeq.c
**	09-may-89 (neil)
**	    Added rule name tracing.
**	26-may-89 (paul)
**	    Increase statement #, cleanup DSH on error recovery.
**	31-may-89 (neil)
**	    Cleanup tracing; modify when context count is set; reset "saved
**	    resource" bit if procedure is loaded.
**	23-jun-89 (neil)
**	    Extended trace for nested procedures: Indicate procedure nesting
**	    level and rule depth.
**	26-sep-89 (neil)
**	    Support for SET NORULES.
**	02-jan-90 (neil)
**	    DSH initialization error handling improved to indicate problem
**	    specifics.
**	03-jan-90 (ralph)
**	    Change interface to QSO_JUST_TRANS
**	10-jan-90 (neil)
**	    Improved DSH cleanup on DSH initialization errors.  Made sure
**	    to confirm allocation error, and to pass a FALSE "release" flag
**	    to qeq_cleanup.
**	09-feb-90 (neil)
**	    Auditing cleanup: only audit the firing of rules and only if
**	    auditing is on (for performance).
**	09-nov-92 (jhahn)
**	    Added handling for byrefs.
**	14-dec-92 (jhahn)
**	    Cleaned up handling of byrefs.
**	12-feb-93 (jhahn)
**	    Added support for statement level rules. (FIPS)
**	24-mar-93 (jhahn)
**	    Various fixes for support of statement level rules. (FIPS)
**	02-apr-93 (jhahn)
**	    Made set input procedures called from rules bump qef_rule_depth.
**	01-may-93 (jhahn)
**	    Undid above change. Instead added new action QEA_INVOKE_RULE.
**	06-jul-93 (robf)
**	    Pass security  label to qeu_secaudit
**	01-sep-93 (jhahn)
**	    Added support for multiple query plans for set input procedures.
**	 7-jan-94 (swm)
**	    Bug #58635
**	    Added PTR cast for qsf_owner which has changed type to PTR.
**	18-may-94 (anitap)
**	    Bug #63465
**	    If error in nested procedure, the whole transaction was being
**	    rolled back. 
**	7-nov-95 (inkdo01)
**	    Changes to replace QEN_ADF structure instances by pointers in
**	    QEF_AHD structures.
**	24-jul-96 (inkdo01)
**	    Added support of global temp table proc parms.
**	4-mar-97 (inkdo01)
**	    Added display of error QE030B (row rule calls SET OF proc).
**	23-may-97 (inkdo01)
**	    Change QE030B to only pass procname, since it is mapped to a 
**	    US error in qeferror, anyway.
**	17-aug-99 (thaju02)
**	    initialize dmt_show.db_tab_id.db_tab_base to 0 prior to calling
**	    dmt_show, to avoid falsely reporting E_QE0018. (b98431)
**	27-apr-01 (inkdo01)
**	    Add code to detect nested/dynamic calls to row procs.
**	15-mar-04 (inkdo01)
**	    dsh_tempTables is now an array of ptrs.
**	17-mar-04 (inkdo01)
**	    We be fixin' a bug in error handlin' when qeq_dsh() doesn't
**	    return a dsh.
**	13-may-04 (inkdo01)
**	    Preserve status across qeq_cleanup calls.
**	18-may-04 (inkdo01)
**	    Quick fix to eliminate QE0018 when QE030D (US09AF) happens.
**	13-Jul-2004 (schka24)
**	    Straighten out which dsh is used where, fix loss of error
**	    code when finding called qp leading to QE0018.
**	13-Dec-2005 (kschendel)
**	    Inlined QEN_ADF changed to pointer, fix here.
**      29-May-2008 (gefei01)
**          Prototype change for qeq_dsh().
**      22-Apr-2009 (hanal04) Bug 121970
**          In printrule tracing print the ahd_pcount not qef_pcount
**          which is set to zero if we are in a sub-procedure.
**	21-Jun-2010 (kschendel) b123775
**	    Combine is-tproc and in-progress args to qeq-dsh.
**	    Make dbp alias a real QSO_NAME.
*/
DB_STATUS
qea_callproc(
QEF_AHD		    *act,
QEF_RCB		    *qef_rcb,
QEE_DSH		    *call_dsh,
i4		    function,		/* Unused */
i4		    state )		/* Unused */
{
    i4		err;
    DB_STATUS		status	= E_DB_OK, savestat;
    QEF_CB		*qef_cb = call_dsh->dsh_qefcb;
    PTR			*cbs = call_dsh->dsh_cbs;
    QEE_DSH		*proc_dsh;	/* DSH for called dbp */
    QEN_ADF		*qen_adf;
    ADE_EXCB		*ade_excb;
    QSF_RCB		qsf_rcb;
    i4		tr1 = 0, tr2 = 0;	/* Dummy trace values */
    DB_ERROR		e_error;		/* To pass to qeu_secaudit */
    i4             page_count;
    bool                is_deferred =
        		  act->qhd_obj.qhd_callproc.ahd_proc_temptable != NULL;
    bool		gttparm = 
			  act->qhd_obj.qhd_callproc.ahd_gttid.db_tab_base != 0;
    bool		need_cleanup = FALSE;
    bool		need_release;
    bool		from_rule =
	                   act->qhd_obj.qhd_callproc.ahd_rulename.db_name[0]
			       != EOS;
    QEE_TEMP_TABLE  *proc_temptable;
    char		*cbuf = qef_cb->qef_trfmt;
    i4			cbufsize = qef_cb->qef_trsize;
    i4			open_count;

    do
    {
	/*
	** This action is called back if a request to CREATE a QP for a
	** CALLPROC fails. In this case we just continue with error processing.
	** No need for another error as CLEAN_RSRC is only set if a client on
	** the outside issued an error knowing we have a stacked environment.
	** (Note: as of the 123775 fixes, we shouldn't ever get here with
	** CLEAN_RSRC set, since qeq-query no longer attempts to execute
	** the action from the sequencer callback.  I'm leaving the code
	** here for now, though.)
	*/
	if ((qef_rcb->qef_intstate & QEF_CLEAN_RSRC) != 0)
	{
	    call_dsh->dsh_error.err_code = E_QE0025_USER_ERROR;
	    qef_rcb->qef_intstate &= ~QEF_CLEAN_RSRC;
	    status = E_DB_ERROR;
	    break;
	}

	if (is_deferred)
	{
	    proc_temptable = call_dsh->dsh_tempTables[act->qhd_obj.qhd_callproc
				    .ahd_proc_temptable->ttb_tempTableIndex];
	    if (proc_temptable->tt_statusFlags & TT_EMPTY)
	     if (from_rule) break;	/* empty ttab in statement rule -
					** nothing to do at all */
	     else status = openTempTable(qef_rcb, call_dsh, act->qhd_obj.qhd_callproc
		   	.ahd_proc_temptable->ttb_tempTableIndex, gttparm);
	    else status = qen_rewindTempTable(call_dsh, act->qhd_obj.
			qhd_callproc.ahd_proc_temptable->ttb_tempTableIndex);
	    if (status != E_DB_OK)
		   break;
	}
	/* If called from a rule & SET NORULES is on, then inhibit execution */
	if (    from_rule
	     && ult_check_macro(&qef_cb->qef_trace, QEF_T_NORULES, &tr1, &tr2)
	   )
	{
	    /* Trace inhibited rule if required */
	    if (ult_check_macro(&qef_cb->qef_trace, QEF_T_RULES, &tr1, &tr2))
	    {
		char	*rn = act->qhd_obj.qhd_callproc.ahd_rulename.db_name;
		STprintf(cbuf, "PRINTRULES: Rule '%.*s' suppressed\n",
			    qec_trimwhite(DB_RULE_MAXNAME, rn), rn);
        	qec_tprintf(qef_rcb, cbufsize, cbuf);
	    }
	    call_dsh->dsh_error.err_code = E_QE0125_RULES_INHIBIT;
	    status = E_DB_ERROR;
	    break;
	} /* If rules off */

	/*
	** Security audit rule firing  - check that is first time (not
	** recreation), is a rule and, for performance, that we really
	** need to audit.
	*/
	if (   (qef_rcb->qef_intstate & QEF_DBPROC_QP) == 0
	    && (act->qhd_obj.qhd_callproc.ahd_rulename.db_name[0] != EOS)
	    && (Qef_s_cb->qef_state & QEF_S_C2SECURE)
	   )
	{
	    status = qeu_secaudit(FALSE, qef_cb->qef_ses_id,
		    act->qhd_obj.qhd_callproc.ahd_rulename.db_name,
		    (DB_OWN_NAME *)&act->qhd_obj.qhd_callproc.ahd_ruleowner,
		    sizeof(act->qhd_obj.qhd_callproc.ahd_rulename), SXF_E_RULE,
		    I_SX202F_RULE_ACCESS, SXF_A_SUCCESS | SXF_A_EXECUTE,
		    &e_error);

	    if (status != E_DB_OK)
	    {
		call_dsh->dsh_error.err_code = e_error.err_code;
		break;
	    }
	}

	/* Actually execute a CALLPROC. */
	/* We generate an actual parameter list, save the current   */
	/* execution context, stack the DSH and setup the new	    */
	/* execution context. Processing then continues with the    */
	/* new QP. */

	/* Save the current execution context as represented by	    */
	/* QEF_RCB and the current DSH. */
	STRUCT_ASSIGN_MACRO(*qef_rcb, *call_dsh->dsh_saved_rcb);
	call_dsh->dsh_act_ptr = act;

	qen_adf = act->qhd_obj.qhd_callproc.ahd_procparams;
	if (qen_adf != NULL)
	{
	    /* Compute the actual parameters for this procedure	    */
	    /* call. */
	    qef_rcb->qef_pcount = act->qhd_obj.qhd_callproc.ahd_pcount;
	    ade_excb = (ADE_EXCB *)cbs[qen_adf->qen_pos];
	    ade_excb->excb_seg = ADE_SMAIN;
	    status = ade_execute_cx(call_dsh->dsh_adf_cb, ade_excb);
	    if (status != E_DB_OK)
	    {
		status = qef_adf_error(&call_dsh->dsh_adf_cb->adf_errcb,
			status, qef_cb, &call_dsh->dsh_error);
		if (status != E_DB_OK)
		    break;
	    }
	}
	else
	{
	    /* No actual parameters */
	    qef_rcb->qef_pcount = 0;
	}

	/*
	** If tracing rules and first time through then display
	** rule/procedure information.
	*/

	if ((qef_rcb->qef_intstate & QEF_DBPROC_QP) == 0)
	{
	    if (ult_check_macro(&qef_cb->qef_trace, QEF_T_RULES, &tr1, &tr2))
	    {
		char	*rn, *pn;	/* Rule/procedure names */

		rn = act->qhd_obj.qhd_callproc.ahd_rulename.db_name;
		pn = act->qhd_obj.qhd_callproc.ahd_dbpalias.qso_n_id.db_cur_name;
		/* Tailor trace for rules vs nested procedures */
		STprintf(cbuf, *rn == EOS ?
		     "PRINTRULES 1: Executing procedure '%.*s'\n" :
		     "PRINTRULES 1: Executing procedure '%.*s' from rule '%.*s'\n",
		     qec_trimwhite(DB_DBP_MAXNAME, pn), pn,
		     qec_trimwhite(DB_RULE_MAXNAME, rn), rn);
        	qec_tprintf(qef_rcb, cbufsize, cbuf);
		STprintf(cbuf,
		     "PRINTRULES 2: Rule/procedure depth = %d/%d, parameters passed = %d\n",
		     qef_rcb->qef_rule_depth,
		     qef_rcb->qef_context_cnt + 1, 
		     act->qhd_obj.qhd_callproc.ahd_pcount);
        	qec_tprintf(qef_rcb, cbufsize, cbuf);
	    } /* If tracing rules */
	}

	/*
	** Indicate that we have nested one more level, generate an error if
	** we are nested too deeply. Context count is actually set later.
	*/
	if (qef_cb->qef_max_stack < qef_rcb->qef_context_cnt + 1)
	{
	    status = E_DB_ERROR;
	    qef_error(E_QE0208_EXCEED_MAX_CALL_DEPTH, 0L, status, &err,
		&call_dsh->dsh_error, 1, sizeof(qef_cb->qef_max_stack),
		&qef_cb->qef_max_stack);
	    call_dsh->dsh_error.err_code = E_QE0122_ALREADY_REPORTED;
	    break;
	}

	if (gttparm) 
	{
	    STRUCT_ASSIGN_MACRO(act->qhd_obj.qhd_callproc.ahd_gttid,
		qef_rcb->qef_setInputId);	/* copy temptab ID */
	    page_count = 1;
	    is_deferred = TRUE;
	}
	else if (is_deferred)
        {
            DMT_CB      *dmt_cb = proc_temptable->tt_dmtcb;
            DMT_SHW_CB  dmt_show;
            DMT_TBL_ENTRY       dmt_tbl_entry;

            dmt_show.type = DMT_SH_CB;
            dmt_show.length = sizeof(DMT_SHW_CB);
            dmt_show.dmt_session_id = qef_cb->qef_ses_id;
            dmt_show.dmt_db_id = qef_rcb->qef_db_id;
            dmt_show.dmt_tab_id.db_tab_base = 0;
            dmt_show.dmt_flags_mask = DMT_M_TABLE | DMT_M_ACCESS_ID;
            dmt_show.dmt_char_array.data_address = NULL;
            dmt_show.dmt_table.data_address = (PTR) &dmt_tbl_entry;
            dmt_show.dmt_table.data_in_size = sizeof(DMT_TBL_ENTRY);
            dmt_show.dmt_record_access_id = dmt_cb->dmt_record_access_id;
            status = dmf_call(DMT_SHOW, &dmt_show);
            if (status != E_DB_OK)
	    {
		STRUCT_ASSIGN_MACRO(dmt_show.error, call_dsh->dsh_error);
                break;
	    }
            page_count = dmt_tbl_entry.tbl_page_count;
            STRUCT_ASSIGN_MACRO(dmt_cb->dmt_id,
                               qef_rcb->qef_setInputId);
        }
        else
        {
            page_count = -1;
            MEfill(sizeof(DB_TAB_ID), (u_char)0,
                   (PTR)&qef_rcb->qef_setInputId);
        }
        STRUCT_ASSIGN_MACRO(act->qhd_obj.qhd_callproc.ahd_procedureID,
                           qef_rcb->qef_dbpId);

	/* Get the id of the procedure to call */
	STRUCT_ASSIGN_MACRO(act->qhd_obj.qhd_callproc.ahd_dbpalias.qso_n_id, qef_rcb->qef_qp);
	qef_rcb->qef_qso_handle = NULL;
	/* Set the full name of the procedure into the RCB in case  */
	/* we have to call PSF to define the procedure. */
	qef_rcb->qef_dbpname = act->qhd_obj.qhd_callproc.ahd_dbpalias;

	/* Lookup this procedure name as a QSF alias. At this time  */
	/* we do not have a valid DB_CURSOR_ID because we do not    */
	/* have the timestamp for the QP object. Ask QSF to look    */
	/* this up for us. If found, we continue executing, if not  */
	/* return to SCF to define this procedure.		    */
	qsf_rcb.qsf_type = QSFRB_CB;
	qsf_rcb.qsf_ascii_id = QSFRB_ASCII_ID;
	qsf_rcb.qsf_length = sizeof(QSF_RCB);
	qsf_rcb.qsf_owner = (PTR)DB_QEF_ID;
	qsf_rcb.qsf_sid = qef_rcb->qef_cb->qef_ses_id;

	qsf_rcb.qsf_feobj_id.qso_type = QSO_ALIAS_OBJ;
	qsf_rcb.qsf_feobj_id.qso_lname =
	    sizeof(qsf_rcb.qsf_feobj_id.qso_name);
	MEcopy((PTR)&act->qhd_obj.qhd_callproc.ahd_dbpalias,
	       sizeof(qsf_rcb.qsf_feobj_id.qso_name),
	       (PTR)qsf_rcb.qsf_feobj_id.qso_name);
        qsf_rcb.qsf_lk_state = QSO_FREE;
	status = qsf_call(QSO_JUST_TRANS, &qsf_rcb);
	if (DB_FAILURE_MACRO(status))
	{
	    /* No such procedure in QSF, ask SCF to define it */
	    /* Tell SCF to call us back even if the porcedure	    */
	    /* cannot be loaded. We will need to clean up */
	    qef_rcb->qef_intstate |= QEF_DBPROC_QP;
	    call_dsh->dsh_error.err_code = E_QE0119_LOAD_QP;
	    break;
	}
	else
	{
	    /*
	    ** The procedure was found - make sure "saved" bit isn't on for
	    ** the scope of this execution.  It may get turned back on if
	    ** the QP or DSH is found to be invalid but then we'll re-enter
	    ** here (to try again) and turn it off.
	    */
	    qef_rcb->qef_intstate &= ~QEF_DBPROC_QP;
	}

	/* Increase context count now that we've loaded the QP */
	qef_rcb->qef_context_cnt++;

	/* Procedure in QSF, load the timestamp into the QEF_RCB    */
	/* to allow normal QEF processing to continue.		    */
	MEcopy((PTR)qsf_rcb.qsf_obj_id.qso_name, sizeof(DB_CURSOR_ID),
	       (PTR)&qef_rcb->qef_qp);
	status = qeq_dsh(qef_rcb, 0 , &proc_dsh, QEQDSH_IN_PROGRESS, page_count);
	if (DB_FAILURE_MACRO(status))
	{
	    char	*rn, *pn;	/* Rule/procedure names */

	    STRUCT_ASSIGN_MACRO(qef_rcb->error, call_dsh->dsh_error);

	    if (call_dsh->dsh_error.err_code == E_QE0023_INVALID_QUERY)
	    {
		/* No such procedure in QSF, ask SCF to define it */
		/* Tell SCF to call us back even if the porcedure */
		/* cannot be loaded. We will need to clean up     */
		qef_cb->qef_dsh = (PTR) call_dsh;
		qef_rcb->qef_qp = call_dsh->dsh_saved_rcb->qef_qp;
		qef_rcb->qef_intstate |= QEF_DBPROC_QP;
		call_dsh->dsh_error.err_code = E_QE0119_LOAD_QP;
		qef_rcb->qef_context_cnt--;
		break;
	    }
	    /*
	    ** The QP DSH is invalid for some reason. Generate error and return.
	    ** If any allocation error then change to useful error message. 
	    */
	    if (   call_dsh->dsh_error.err_code == E_UL0005_NOMEM 
	        || call_dsh->dsh_error.err_code == E_QS0001_NOMEM 
	        || call_dsh->dsh_error.err_code == E_QE001E_NO_MEM 
		|| call_dsh->dsh_error.err_code == E_QE000D_NO_MEMORY_LEFT
		|| call_dsh->dsh_error.err_code == E_QE030B_RULE_PROC_MISMATCH)
	    {
		pn =
		 act->qhd_obj.qhd_callproc.ahd_dbpalias.qso_n_id.db_cur_name;
		rn = act->qhd_obj.qhd_callproc.ahd_rulename.db_name;
		if (*rn == EOS)
		    rn = "NULL                                   ";
		if (call_dsh->dsh_error.err_code == E_QE030B_RULE_PROC_MISMATCH)
		    qef_error(E_QE030B_RULE_PROC_MISMATCH, 0L, status, &err,
		    &call_dsh->dsh_error, 1,
		    /* qec_trimwhite(DB_RULE_MAXNAME, rn), rn, */
		    qec_trimwhite(DB_DBP_MAXNAME, pn), pn);
		else qef_error(E_QE0199_CALL_ALLOC, 0L, status, &err,
		    &call_dsh->dsh_error, 3,
		    qec_trimwhite(DB_DBP_MAXNAME, pn), pn,
		    qec_trimwhite(DB_RULE_MAXNAME, rn), rn,
		    sizeof(qef_rcb->qef_context_cnt),&qef_rcb->qef_context_cnt);
		call_dsh->dsh_error.err_code = E_QE0122_ALREADY_REPORTED;
	    }

	    /*
	    ** Now clean up and restore to state before routine entry.
	    ** Pass in FALSE for release as if the DSH is NULL we do NOT want
	    ** to cause cleanup to release all DSH's for this session
	    ** (qee_cleanup).  If the DSH is not NULL it will be cleaned up at
	    ** the end of the query.
	    */
	    need_cleanup = TRUE;
	    need_release = FALSE;
	    break;
	}

	if (proc_dsh->dsh_qp_ptr->qp_status & QEQP_ROWPROC)
	{
	    char	*pn;
	    /* Row producing procs cannot be invoked by QEA_CALLPROC (which
	    ** implies either nested proc call or dynamic SQL proc call). */
	    pn = act->qhd_obj.qhd_callproc.ahd_dbpalias.qso_n_id.db_cur_name;
	    qef_error(E_QE030D_NESTED_ROWPROCS, 0L, E_DB_ERROR, &err,
		&call_dsh->dsh_error, 1,
		qec_trimwhite(DB_DBP_MAXNAME, pn), pn);
	    status = E_DB_ERROR;
	    break;
	}
	/* Found QP and DSH, stack old context */
	proc_dsh->dsh_stack = call_dsh;

	proc_dsh->dsh_stmt_no = qef_cb->qef_stmt++;

	qef_cb->qef_dsh = (PTR) proc_dsh;

	qef_cb->qef_open_count++;

	/* Initialize procedure parameters (& user params - even if wrong) */
	if (proc_dsh->dsh_qp_ptr->qp_ndbp_params != 0 || qef_rcb->qef_pcount > 0)
	{
	    status = qee_dbparam(qef_rcb,
				 proc_dsh,
				 call_dsh,
				 act->qhd_obj.qhd_callproc.ahd_params,
				 act->qhd_obj.qhd_callproc.ahd_pcount, TRUE);
	    if (DB_FAILURE_MACRO(status))
	    {
		/* If we fail after acquiring the DSH, we need to */
		/* deallocate the DSH and recover back to the original	    */
		/* calling state. */
		STRUCT_ASSIGN_MACRO(proc_dsh->dsh_error, call_dsh->dsh_error);
		qef_cb->qef_open_count--;
		need_cleanup = TRUE;
		need_release = TRUE;
		break;
	    }
	}
	if (is_deferred)
	{
	    /* FIXME should error if it's null */
	    if (proc_dsh->dsh_qp_ptr->qp_setInput != NULL)
		STRUCT_ASSIGN_MACRO(qef_rcb->qef_setInputId,
			* (DB_TAB_ID *)(proc_dsh->dsh_row[proc_dsh->dsh_qp_ptr->
					 qp_setInput->vl_tab_id_index]));
	}
    } while (FALSE);

    if (need_cleanup)
    {
	/* error in a nested DB procedure, abort up to the beginning of the
	** procedure if there are no other cursors opened. We
	** guarantee that by decrementing the qef_open_count. If the
	** count becomes zero, qeq_cleanup will abort to the last internal
	** savepoint. Fix for bug 63465.
	*/

	savestat = status;
	open_count = qef_cb->qef_open_count;
	
	while (qef_cb->qef_open_count > 0) 
	      qef_cb->qef_open_count--;
	
	status = qeq_cleanup(qef_rcb, status, need_release);

	status = savestat;
	qef_cb->qef_open_count = open_count;

	qef_cb->qef_dsh = (PTR) call_dsh;
	qef_rcb->qef_context_cnt--;
	qef_rcb->qef_pcount = call_dsh->dsh_saved_rcb->qef_pcount;
	qef_rcb->qef_usr_param = call_dsh->dsh_saved_rcb->qef_usr_param;
	qef_rcb->qef_qp = call_dsh->dsh_saved_rcb->qef_qp;
	qef_rcb->qef_qso_handle = call_dsh->dsh_saved_rcb->qef_qso_handle;
	call_dsh->dsh_qef_rowcount = call_dsh->dsh_saved_rcb->qef_rowcount;
	call_dsh->dsh_qef_targcount = call_dsh->dsh_saved_rcb->qef_targcount;
	call_dsh->dsh_qef_output = call_dsh->dsh_saved_rcb->qef_output;
	call_dsh->dsh_qef_count = call_dsh->dsh_saved_rcb->qef_count;
    }
    return (status);
}
Beispiel #7
0
DB_STATUS
qel_c0_cre_lnk(
QEF_RCB		*v_qer_p ) 
{
    DB_STATUS		status;
    QEF_CB		*qef_cb = v_qer_p->qef_cb;
    QES_DDB_SES		*dds_p = & v_qer_p->qef_cb->qef_c2_ddb_ses;
    QED_DDL_INFO	*ddl_p = & v_qer_p->qef_r3_ddb_req.qer_d7_ddl_info;
    DD_0LDB_PLUS	*plus_p = & ddl_p->qed_d6_tab_info_p->
			    dd_t9_ldb_p->dd_i2_ldb_plus;
    DD_CAPS		*caps_p = & plus_p->dd_p3_ldb_caps;
    DD_LDB_DESC		ldb,		    /* for replicating LDB desc */
			*ldb_p = & ldb,
			*cdb_p = & dds_p->qes_d4_ddb_p->
			    dd_d3_cdb_info.dd_i1_ldb_desc,
			*ddl_ldb_p = & ddl_p->qed_d6_tab_info_p->
			    dd_t9_ldb_p->dd_i1_ldb_desc;
    QEC_D9_TABLEINFO	tabinfo;	    /* used for table info of link */
    QEC_D2_LDBIDS	ldbids;		    /* used for internal LDB id info */
    QEC_D5_LONG_LDBNAMES
			longnames;	    /* used for excessively long LDB
					    ** name */
    QEC_L16_TABLES	tables;		    /* used for IITABLES-style info */
    QEC_D6_OBJECTS	objects;	    /* used for object info */
    QEC_L6_INDEXES	indexes;
    QEC_MIN_CAP_LVLS	pre_mins,
			aft_mins;
    QEC_LINK		link,		    /* used as global control block */
			*link_p = & link;
    QEQ_1CAN_QRY	del,
			ins,
			sel,
			upd,		    /* used for ordering canned query */
			*upd_p = & upd;
    u_i4		len;
    SYSTIME		now;
    bool		log_ddl_56 = FALSE,
			log_err_59 = FALSE;
    i4		i4_1,
			i4_2;
    QEC_INDEX_ID	ndx_ids[QEK_0MAX_NDX_COUNT + 1];
					    /* working space for index ids */
    RQB_BIND		rq_bind[QEC_CAT_COL_COUNT_MAX + 1];
    QEC_D7_OBJECT_BASE	obj_base,
			*base_p = & obj_base;
    i4			xact_mode;
    char		*cbuf = v_qer_p->qef_cb->qef_trfmt;
    i4			cbufsize = v_qer_p->qef_cb->qef_trsize;

    
    if (ult_check_macro(& qef_cb->qef_trace, QEF_TRACE_DDB_LOG_DDL_56,
	    & i4_1, & i4_2))
    {
        log_ddl_56 = TRUE;
    }
    
    if (ult_check_macro(& qef_cb->qef_trace, QEF_TRACE_DDB_LOG_ERR_59,
	    & i4_1, & i4_2))
    {
        log_err_59 = TRUE;
    }
    sel.qeq_c2_rqf_bind_p = rq_bind;		/* must set up */
    del.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    ins.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;
    upd.qeq_c2_rqf_bind_p = (RQB_BIND *) NULL;

    /* 1.  set up control block */

    if (dds_p->qes_d7_ses_state == QES_4ST_REFRESH)	
						/* REGISTER WITH REFRESH ? */
	STRUCT_ASSIGN_MACRO(ddl_p->qed_d7_obj_id, tabinfo.d9_1_obj_id);
						/* yes */
    else					/* no */
    {
	tabinfo.d9_1_obj_id.db_tab_base = 0;	/* unknown */
	tabinfo.d9_1_obj_id.db_tab_index = 0;	/* always 0 for non-index */
    }
    link_p->qec_1_ddl_info_p = ddl_p;
    link_p->qec_2_tableinfo_p = & tabinfo;
    link_p->qec_3_ldb_id = 0;			
    link_p->qec_4_col_cnt = 0;
    MEfill(DB_DB_MAXNAME, ' ', link_p->qec_5_ldb_alias);
    link_p->qec_6_select_p = & sel;
    link_p->qec_7_ldbids_p = & ldbids;
    link_p->qec_8_longnames_p = & longnames;
    link_p->qec_9_tables_p = & tables;
    link_p->qec_10_haves = QEC_07_CREATE;
    if (caps_p->dd_c6_name_case == DD_2CASE_UPPER)
	link_p->qec_10_haves |= QEC_06_UPPER_LDB;
    if (caps_p->dd_c1_ldb_caps & DD_7CAP_USE_PHYSICAL_SOURCE)
	link_p->qec_10_haves |= QEC_10_USE_PHY_SRC;
    if (caps_p->dd_c2_ldb_caps & DD_201CAP_DIFF_ARCH)
	link_p->qec_10_haves |= QEC_11_LDB_DIFF_ARCH;

    /* make a copy of the LDB descriptor for non-$ingrs access if necessary */

    if (ddl_ldb_p->dd_l1_ingres_b)
    {
	/* make a copy for non-$ingres access */

	STRUCT_ASSIGN_MACRO(*ddl_ldb_p, ldb);
	ldb_p->dd_l1_ingres_b = FALSE;
	ldb_p->dd_l5_ldb_id = DD_0_IS_UNASSIGNED;
    }
    else
    {	
	/* use provided LDB descriptor but determine if LDB has a long name */

	qed_u0_trimtail(
		ddl_ldb_p->dd_l3_ldb_name, 
		(u_i4) DD_256_MAXDBNAME,
		ldb_p->dd_l3_ldb_name);

	len = STlength(ldb_p->dd_l3_ldb_name);
	if (len > DB_DB_MAXNAME)
	    link_p->qec_10_haves |= QEC_04_LONG_LDBNAME;

	ldb_p = ddl_ldb_p;
    }
    link_p->qec_11_ldb_obj_cnt = 0;
    link_p->qec_12_indexes_p = & indexes;
    link_p->qec_13_objects_p = & objects;
    link_p->qec_15_ndx_cnt = 0;
    link_p->qec_16_ndx_ids_p = ndx_ids;
    link_p->qec_19_ldb_p = ldb_p;
    link_p->qec_20_rqf_bind_p = rq_bind;
    link_p->qec_21_delete_p = & del;
    link_p->qec_22_insert_p = & ins;
    link_p->qec_23_update_p = & upd;

    status = qed_u8_gmt_now(v_qer_p, link_p->qec_24_cur_time);
    if (status)
	return(status);

    link_p->qec_24_cur_time[DD_25_DATE_SIZE] = EOS;
    link_p->qec_25_pre_mins_p = & pre_mins;
    link_p->qec_26_aft_mins_p = & aft_mins;
    link_p->qec_27_select_cnt = 0;
    link_p->qec_28_iistats_cnt = 0;
    
    TMnow(& now);
    link_p->qec_17_ts1 = now.TM_secs;
    link_p->qec_18_ts2 = now.TM_msecs;
    
    /* 2.  inform TPF of update intention on CDB (note that only CREATE does
    **	   LDB retrievals */

    /* 2.1 2PC is required if DDL concurrency is off. */
    if (dds_p->qes_d9_ctl_info & QES_01CTL_DDL_CONCURRENCY_ON)
	xact_mode = QEK_4TPF_1PC;
    else
	xact_mode = QEK_3TPF_UPDATE;

    status = qet_t5_register(v_qer_p, cdb_p, DB_SQL, xact_mode);
    if (status)
	return(status);

    if (log_ddl_56)
    {
	/* display beginning, CDB and LDB info */

	STprintf(cbuf, "\n%s %p: %s REGISTRATION begins%s\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    IIQE_65_tracing,
	    IIQE_62_3dots);
        qec_tprintf(v_qer_p, cbufsize, cbuf);

	STprintf(cbuf, 
	    "%s %p: ...the CDB:\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
	qed_w1_prt_ldbdesc(v_qer_p, cdb_p);

	STprintf(cbuf, 
	    "%s %p: ...the LDB:\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
	qed_w1_prt_ldbdesc(v_qer_p, ldb_p);

	STprintf(cbuf, "\n");
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }
    /* 3.  update OBJECT_BASE in II_DD_DB_OBJECT_BASE */

    upd_p->qeq_c1_can_id = UPD_716_DD_DDB_OBJECT_BASE;
    upd_p->qeq_c3_ptr_u.d7_object_base_p = base_p;
    upd_p->qeq_c4_ldb_p = cdb_p;

    status = qel_u1_update(v_qer_p, link_p);
    if (status)
	goto END_TRACING;

    /* 4.  enter phase 1: set up necessary information */

    status = qel_c1_cre_p1(v_qer_p, link_p);
    if (status)
	goto END_TRACING;

    /* 2.  enter phase 2: promote information into STAR catalogs */

    status = qel_c2_cre_p2(v_qer_p, link_p);
    if (status)
	v_qer_p->qef_cb->qef_abort = TRUE;

END_TRACING:

    if (log_ddl_56)
    {
	/* display end tracing message */

	STprintf(cbuf, 
	    "%s %p: %s REGISTRATION ends\n\n",
	    IIQE_61_qefsess,
	    (PTR) v_qer_p->qef_cb,
	    IIQE_65_tracing);
        qec_tprintf(v_qer_p, cbufsize, cbuf);
    }

    return(status);
}