Пример #1
0
BOOL GetReadOnly(char *dsn)
{
    char readOnly[2] = "\0";

    SQLGetPrivateProfileString (dsn, KEY_READONLY, "", readOnly,
        sizeof(readOnly),ODBC_INI);
    if (!CMcmpnocase(&readOnly[0],"Y"))
        return 1;
    return 0;
}
Пример #2
0
/*
** Name: check_path_chars   - test path characters are supported.
**
** Description:
**  Test that the characters in the path are permitted.
**
** Inputs:
**  loc                 Pointer to location structure containing path.
**
** Outputs:
**  status              More detailed error code for failure.
**
** Returns:
**  result      OK      No invalid characters found.
**              FAIL    Invalid characters found in path.
**
** History:
**      14-Feb-2005 (fanra01)
**          Create to replace call to LOisvalid.
**	03-Jun-2005 (drivi01)
**	    Replaced Window's portion of check_path_chars
**	    with LOisvalid.
**  11-Jul-2005 (fanra01)
**      Add status output.
*/
static i4
check_path_chars( LOCATION* loc, STATUS* status )
{
    i4 result = OK;
    char	dev[MAX_LOC];
    char	path[MAX_LOC];
    char	file[MAX_LOC];
    char	ext[MAX_LOC];
    char	vers[MAX_LOC];
    char	*p;

# if defined(NT_GENERIC)

    if (!LOisvalid( loc, &result ))
    {
        if (status != NULL)
        {
            *status = result;
        }
        return FAIL;
    }

# else  /* NT_GENERIC */
    if (LOdetail( loc, dev, path, file, ext, vers ) != OK)
        return FAIL;
    for (p = path; *p != EOS; CMnext(p))
    {
	if (!(CMalpha(p) || CMdigit(p) || CMcmpnocase(p, PATH_SEPARATOR) ||
        '_' || *p == ' '))
	    return FAIL;
    }
    for (p = file; *p != EOS; CMnext(p))
    {
	if (!(CMalpha(p) || CMdigit(p) || *p == '_' || *p == ' '))
	    return FAIL;
    }
    for (p = ext; *p != EOS; CMnext(p))
    {
	if (!(CMalpha(p) || CMdigit(p) || *p == '_' || *p == ' '))
	    return FAIL;
    }
# endif /* NT_GENERIC */
    
    return(result);
}
Пример #3
0
/*{
** Name: psq_parseqry	- Parse a query and return a data structure
**
**  INTERNAL PSF call format: status = psq_parseqry(&psq_cb, &sess_cb);
**
**  EXTERNAL call format:    status = psq_call(PSQ_PARSEQRY, &psq_cb, &sess_cb);
**
** Description:
**	This function will parse a query in QSF memory.  It will return a
**	data structure (such as a query tree), and a code telling what kind of
**	query was just parsed (e.g. a copy statement).  This code will be
**	called the "query mode".  For qrymod definitions, it will store a
**	modified version of the query text in QSF, for later insertion in the
**	iiqrytext system relation.
**
**	This function will check the syntax of each statement, and will perform
**	some semantic validations.  The syntax checking will be rather simple:
**	each statement will either be right or wrong, and a syntax error will
**	cause the whole go block to be aborted.  Semantic checks will be more
**	complicated; some of them will cause warnings (which will allow the
**	statement to continue), and some will cause errors (causing the
**	statement to be aborted).  It should be noted that the semantic checks
**	will not be the same in the Jupiter version as in previous versions;
**	in the Jupiter version, for instance, the parser won't check for whether
**	the statement is valid inside a multi-query transaction.
**
**	Sometimes it will be found that the definition of a view, permit, or
**	integrity is out of date.  When this happens, this function will return
**	an error status saying so, and an id for finding the query text in the
**	iiqrytext relation, so that the definition can be re-parsed and
**	re-stored.  Accordingly, this function has an option by which one can
**	tell it to get the query text out of the iiqrytext relation instead of
**	QSF.
**
**	When a statement is parsed that creates a new cursor, the parser will
**	assign a cursor id to the cursor, create a cursor control block
**	containing information about the cursor, and return the cursor id inside
**	with the query tree representing the cursor.  This cursor id will be
**	used throughout the session to uniquely identify the cursor.  When a
**	"close cursor" statement is parsed, the parser will deallocate the
**	control block associated with the cursor.
**
**	The parser will automatically apply view, permit, and integrity
**	processing to any data manipulation query it parses.  This will not
**	require a separate call to the parser.
**
**	Multi-statement go blocks are no longer allowed, as they used to be in
**	previous versions.  This parser can handle only one statement at a time.
**
** Inputs:
**      psq_cb
**          .psq_qid                    A unique identifier for getting the
**					query text from QSF.
**	    .psq_iiqrytext		TRUE means to get the query text from
**					the iiqrytext relation, not QSF.
**	    .psq_txtid			Query text id key into iiqrytext
**					relation; used only if above is true.
**	sess_cb				Pointer to the session control block
**
** Outputs:
**      psq_cb
**	    .psq_qlang			The language of the query text.
**          .psq_mode                   The query mode (a code telling what
**					kind of query was just parsed).
**	    .psq_result			QSF id for the data structure produced
**					(query tree, or control block stored as
**					QEP).
**	    .psq_txtid			Query text id key into iiqrytext
**					relation; filled in if some qrymod
**					object needs redefining.
**	    .psq_mnyfmt			Set on a "set money_format" or
**					"set money_prec" statement
**	    .psq_dtefmt			Set on a "set date_format" statement
**	    .psq_decimal		Set on a "set decimal" statement
**          .psq_error                  Standard error block
**		E_PS0000_OK		    Success
**		E_PS0001_USER_ERROR	    Mistake by user
**		E_PS0002_INTERNAL_ERROR	    Internal inconsistency inside PSF
**		E_PS0B01_OUTDATED_VIEW	    View out of date; must re-define
**		E_PS0B02_OUTDATED_PERMIT    Permit out of date; must re-define
**		E_PS0B03_OUTDATED_INTEG	    Integrity out of date; must re-def.
**		E_PS0B04_CANT_GET_TEXT	    Can't get query text
**	    .psq_txtout			QSF id for the create procedure stmt to
**					be stored in the system catalog.
**
**	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:
**	    Stores query tree or control block in QSF.
**	    Can open a cursor.
**
** History:
**	01-oct-85 (jeff)
**          written
**	19-sep-86 (daved)
**	    end of qry should point to last char. This char should be a space.
**	    this makes the scanner's job easier
**	27-jan-87 (daved)
**	    add the printqry set command.
**	02-oct-87 (stec)
**	    Removed pss_journaling flag initialization;
**	    must be initialized in psqbgnses.c
**	19-jan-88 (stec)
**	    Changed initialization od pst_resloc.
**	25-may-88 (stec)
**	    Made changes in connection with DB procedures.
**	    QSF object of QP type has to be destroyed if
**	    translate_or_define worked for CREATE PROCEDURE. 
**	23-aug-88 (stec)
**	    Initialize qso_handle in QSO_OBIDs in psq_cb.
**	21-apr-89 (neil)
**	    Extracted some initialization (psq_cbinit) from psq_parseqry to
**	    allow it to be called from other routines as well.
**	11-dec-89 (ralph)
**	    Change interface to QSO for dbprocs
**	12-sep-90 (teresa)
**	    fix faulty pss_retry logic.
**	15-jun-92 (barbara)
**	    Sybil merge.  Pass in sess control block to pst_clrrng.
**	23-nov-92 (barbara)
**	    For Star, accept range statement as the one and only allowable
**	    QUEL statement.  This is to support old FE's which use the range
**	    statement as a quick way to ascertain table existence.  FEs of
**	    >= 6.5 vintage use a table_resolve() function, so at some point
**	    we can remove the QUEL range table statement support for Star.
**      24-nov-92 (ralph)
**          CREATE SCHEMA:
**          Initialize pss_prvgoval
**	22-dec-92 (rblumer)
**	    clean up after pss_tchain2 just like pss_tchain.
**	25-may-93 (rog)
**	    Move clean-up/exit code into psq_cbreturn() and then call it.
**	11-oct-93 (swm)
**	    Bug #56448
**	    Declared trbuf for psf_display() to pass to TRformat.
**	    TRformat removes `\n' chars, so to ensure that psf_scctrace()
**	    outputs a logical line (which it is supposed to do), we allocate
**	    a buffer with one extra char for NL and will hide it from TRformat
**	    by specifying length of 1 byte less. The NL char will be inserted
**	    at the end of the message by psf_scctrace().
**	16-mar-94 (andre)
**	    if performing an internal PSF retry and trace point ps129 (same as 
*8	    SET PRINTQRY) is set, instead of redisplaying the query we will 
*8	    tell the user that we are retrying the last query.
**	28-feb-2005 (wanfr01)
**	    Bug 64899, INGSRV87
**	    Add stack overflow handler for TRU64.
**	17-mar-06 (dougi)
**	    Init pss_hintcount to 0 for optimizer hints project.
**	23-june-06 (dougi)
**	    Init pss_stmtno to 1 for procedure debugging.
**	05-sep-06 (toumi01)
**	    Init pss_stmtno to 0 (to match new "help procedure" numbering)
**	    lest we point, PC register like, to the _following_ statement.
**	15-Sep-2008 (kibro01) b120571
**	    Use same session ID as available in iimonitor
**	16-Sep-2008 (kibro01) b120571
**	    Remove compilation error from cast of sessid
**	16-Feb-2009 (kibro01) b121674
**	    Add version to SESSION BEGINS message in sc930 and give out
**	    data type of parameters.
**	10-Jul-2009 (kibro01) b122299
**	    Increase the version number due to dates being printed out now.
**	15-Jul-2009 (kibro01) b122172
**	    Change QUERY or QUEL to REQUERY or REQUEL when a DB procedure is
**	    reparsed due to being invalidated.
**	23-Jul-2009 (kibro01) b122172
**	    Separate the print_qry_buffer logic to avoid stack size problems.
**	3-Aug-2009 (kibro01) b122393
**	    Use print_qry_buffer_ptr to avoid inlining.
**	4-Aug-2009 (kibro01) b122172
**	    Allow REQUERY/REQUEL through even if the RECREATE flag is set so
**	    we get the useful debug output.
**     28-Oct-2009 (maspa05) b122725
**          ult_print_tracefile now uses integer constants instead of string
**          for type parameter - SC930_LTYPE_PARM instead of "PARM" and so on
**          Also moved function definitions for SC930 tracing to ulf.h
**          The functions involved were - ult_always_trace, ult_open_tracefile
**          ult_print_tracefile and ult_close_tracefile
*/
DB_STATUS
psq_parseqry(
	register PSQ_CB     *psq_cb,
	register PSS_SESBLK *sess_cb)
{
    DB_STATUS		    status;
    DB_STATUS		    ret_val;
    QSF_RCB		    qsf_rb;
    i4		    err_code;
    PSQ_QDESC		    *qdesc;
    i4		    val1 = 0;
    i4		    val2 = 0;
    i4			    i;
    char		    trbuf[PSF_MAX_TEXT + 1]; /* last char for `\n' */

    if ((status = psq_cbinit(psq_cb, sess_cb)) != E_DB_OK)
	return (status);

    /*
    ** The following is particular to queries that must be parsed.
    ** Get query text from QSF and put it in session control block
    ** Initialize the qbuf, nextchar, prevtok, and bgnstmt pointers
    */

    qsf_rb.qsf_type = QSFRB_CB;
    qsf_rb.qsf_ascii_id = QSFRB_ASCII_ID;
    qsf_rb.qsf_length = sizeof(qsf_rb);
    qsf_rb.qsf_owner = (PTR)DB_PSF_ID;
    qsf_rb.qsf_sid = sess_cb->pss_sessid;

    qsf_rb.qsf_obj_id.qso_handle = psq_cb->psq_qid;
    status = qsf_call(QSO_INFO, &qsf_rb);
    if (DB_FAILURE_MACRO(status))
    {
	(VOID) psf_error(E_PS0B04_CANT_GET_TEXT, 0L, PSF_CALLERR, &err_code,
	    &psq_cb->psq_error, 0);
	return (E_DB_ERROR);
    }

    qdesc		    = (PSQ_QDESC*) qsf_rb.qsf_root;

    /* print the qry buffer as long as this isn't a retry 
    ** - although allow through the RECREATE case since it's useful
    ** for debugging to log reparsing an object */
    if ((ult_always_trace() & SC930_TRACE) && 
	( ((sess_cb->pss_retry & PSS_REFRESH_CACHE)==0) ||
	  (sess_cb->pss_dbp_flags & PSS_RECREATE) != 0 ) )
    {
	(*print_qry_buffer_ptr)(psq_cb, qdesc, sess_cb);
    }
    if (ult_check_macro(&sess_cb->pss_trace,
				PSS_PRINT_QRY_TRACE, &val1, &val2))
    {
	if (psf_in_retry(sess_cb, psq_cb))
	{
	    psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1,
		    "\n...retrying last query...\n");
	}
	else
	{
	    psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1,
		    "\nQUERY BUFFER:\n");
	    psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1,
		    "%.#s\n", qdesc->psq_qrysize, qdesc->psq_qrytext);
	    psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1,
		    "\nQUERY PARAMETERS:\n");
	    for (i = 0; i < qdesc->psq_dnum; i++)
	    {
	        psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1,
		  "Parameter : %d\n", i);
	        adu_2prvalue(psf_relay, qdesc->psq_qrydata[i]);
	        psf_display(psf_scctrace, 0, trbuf, sizeof(trbuf) - 1, "\n");
	    }
	}
    }

    sess_cb->pss_bgnstmt    = (u_char*) qdesc->psq_qrytext;
    sess_cb->pss_prvgoval   = (u_char*) NULL;
    sess_cb->pss_prvtok	    = (u_char*) qdesc->psq_qrytext;
    sess_cb->pss_qbuf	    = (u_char*) qdesc->psq_qrytext;
    sess_cb->pss_nxtchar    = (u_char*) qdesc->psq_qrytext;
    sess_cb->pss_endbuf	    = sess_cb->pss_qbuf + qdesc->psq_qrysize - 1;
    sess_cb->pss_dmax	    = qdesc->psq_dnum;
    sess_cb->pss_qrydata    = qdesc->psq_qrydata;
    *sess_cb->pss_endbuf    = ' ';
    sess_cb->pss_lineno	    = 1;	/* Start out at line one */
    sess_cb->pss_stmtno	    = 0;	/* and statement at zero */
    sess_cb->pss_dval	    = 0;
    sess_cb->pss_hintcount  = 0;

    psl_yinit(sess_cb);
    if (psq_cb->psq_qlang == DB_QUEL)
    {
	if (sess_cb->pss_distrib & DB_3_DDB_SESS)
	{
	    char	*c;
	    char	*r = "range";

	    /* skip leading white space chars, if any */
	    for (c = qdesc->psq_qrytext;
		 c <= (char *) sess_cb->pss_endbuf && CMwhite(c);
		 CMnext(c)
		)
	    ;

	    /* compare the first word with "range" */
	    for (;
		 *r != EOS && c <= (char *) sess_cb->pss_endbuf &&
		 !CMcmpnocase(c,r);
		 CMnext(c), CMnext(r)
		)	
	    ;

	    /*
	    ** we will go on to parse this statement iff
	    ** 1) first non-white chars are "range"     AND
	    ** 2) 'e' is followed by a white space
	    */
	    if (*r != EOS || c >= (char *) sess_cb->pss_endbuf || !CMwhite(c))
	    {
		(VOID) psf_error(5212L, 0L, PSF_USERERR, &err_code,
				    &psq_cb->psq_error,0);
		return(E_DB_ERROR);
	    }
	}
	sess_cb->pss_parser = pslparse;
    }
    else
    {
	sess_cb->pss_parser = pslsparse;
    }

    IIEXtry
    {
         status = (*sess_cb->pss_parser)(sess_cb, psq_cb);
    }
    IIEXcatch(pthread_stackovf_e)
    {
	(VOID) psf_error(5212L, 0L, PSF_USERERR, &err_code,
			    &psq_cb->psq_error,0);
    }
    IIEXendtry
    
    ret_val = psq_cbreturn(psq_cb, sess_cb, status);

    return (ret_val);
}
Пример #4
0
i4
STxcompare(
	char	*a_ptr,
	size_t	a_len,
	char	*b_ptr,
	size_t	b_len,
	bool	ic,
	bool	sb)
{
	unsigned char		*ap;
	unsigned char		*bp;
	register size_t	al;
	register size_t	bl;
	i4		ret_val = -2;
	i4		cmp;


	ap = (unsigned char *) a_ptr;
	bp = (unsigned char *) b_ptr;
	al = a_len;

	if (al == 0)
		al = MAXI2;

	bl = b_len;

	if (bl == 0)
		bl = MAXI2;

	if (CMGETDBL)
	{
	    while (ret_val == -2)
	    {
		/* supress blanks in both strings */

		if (sb)
		{
			while (al > 0 && CMspace(ap))
			{
				al -= CMbytecnt(ap);
				CMnext(ap);
			}

			while (bl > 0 && CMspace(bp))
			{
				bl -= CMbytecnt(bp);
				CMnext(bp);
			}
		}


		if (al <= 0)
			ap = (unsigned char *) "";

		if (bl <= 0)
			bp = (unsigned char *) "";

		/* do inequality tests */

		if (ic)
			cmp = CMcmpnocase(ap,bp);
		else
			cmp = CMcmpcase(ap,bp);

		if (cmp < 0)
			ret_val = -1;
		else if (cmp > 0)
			ret_val = 1;
		else if (*ap == '\0')
			ret_val = 0;
		else
		{
			/* go on to the next character */

			al -= CMbytecnt(ap);
			CMnext(ap);
			bl -= CMbytecnt(bp);
			CMnext(bp);
		}
	    }
	}
	else
	{
	    while (ret_val == -2)
	    {
		/* supress blanks in both strings */

		if (sb)
		{
			while (al > 0 && CMspace_SB(ap))
			{
				al -= CMbytecnt_SB(ap);
				CMnext_SB(ap);
			}

			while (bl > 0 && CMspace_SB(bp))
			{
				bl -= CMbytecnt_SB(bp);
				CMnext_SB(bp);
			}
		}


		if (al <= 0)
			ap = (unsigned char *) "";

		if (bl <= 0)
			bp = (unsigned char *) "";

		/* do inequality tests */

		if (ic)
			cmp = CMcmpnocase_SB(ap,bp);
		else
			cmp = CMcmpcase_SB(ap,bp);

		if (cmp < 0)
			ret_val = -1;
		else if (cmp > 0)
			ret_val = 1;
		else if (*ap == '\0')
			ret_val = 0;
		else
		{
			/* go on to the next character */

			al -= CMbytecnt_SB(ap);
			CMnext_SB(ap);
			bl -= CMbytecnt_SB(bp);
			CMnext_SB(bp);
		}
	    }
	}

	return(ret_val);
}
Пример #5
0
DB_STATUS
qel_32_tables(
QEF_RCB		*i_qer_p,
QEC_LINK	*v_lnk_p )
{
    DB_STATUS	    status;
    QES_DDB_SES	    *dds_p = & i_qer_p->qef_cb->qef_c2_ddb_ses;
    QED_DDL_INFO    *ddl_p = v_lnk_p->qec_1_ddl_info_p;
    DD_2LDB_TAB_INFO
		    *tabinfo_p = ddl_p->qed_d6_tab_info_p;
    QEC_L16_TABLES  *tables_p = v_lnk_p->qec_9_tables_p;
    QEQ_1CAN_QRY    *sel_p = v_lnk_p->qec_6_select_p,
		    *ins_p = v_lnk_p->qec_22_insert_p;
						/* working structure */
    DD_LDB_DESC	    *cdb_p = 
			& dds_p->qes_d4_ddb_p->dd_d3_cdb_info.dd_i1_ldb_desc,
		    *ldb_p = v_lnk_p->qec_19_ldb_p;
    u_i4	    l_obj;


    if (v_lnk_p->qec_10_haves & QEC_08_NO_IITABLES)
	return(E_DB_OK);

    /* 1.  set up to retrieve from IITABLES */

    qed_u0_trimtail( tabinfo_p->dd_t1_tab_name, (u_i4) DB_TAB_MAXNAME,
		    tables_p->l16_1_tab_name);
    qed_u0_trimtail( tabinfo_p->dd_t2_tab_owner, (u_i4) DB_OWN_MAXNAME,
		    tables_p->l16_2_tab_owner);

    sel_p->qeq_c1_can_id = SEL_117_II_TABLES;
    sel_p->qeq_c3_ptr_u.l16_tables_p = tables_p;
    sel_p->qeq_c4_ldb_p = ldb_p;
    sel_p->qeq_c2_rqf_bind_p = v_lnk_p->qec_20_rqf_bind_p;

    /* 2.  send SELECT query and fetch first tuple */

    status = qel_s4_prepare(i_qer_p, v_lnk_p);
    if (status)
	return(status);
        
    if (! sel_p->qeq_c5_eod_b)
    {
	status = qel_s3_flush(i_qer_p, v_lnk_p);
	if (status)
	    return(status);
    }

    if (v_lnk_p->qec_27_select_cnt != 1)
    {
	status = qed_u1_gen_interr(& i_qer_p->error);
	return(status);
    }

    if (v_lnk_p->qec_10_haves & QEC_10_USE_PHY_SRC)
    {
	/* 3.  read remaining information from the LDB's IIPHYSICAL_TABLES */

	sel_p->qeq_c1_can_id = SEL_113_II_PHYSICAL_TABLES;

	/* 3.1  send SELECT query and fetch first tuple */

	status = qel_s4_prepare(i_qer_p, v_lnk_p);
	if (status)
	    return(status);
        
	if (! sel_p->qeq_c5_eod_b)
	{
	    status = qel_s3_flush(i_qer_p, v_lnk_p);
	    if (status)
		return(status);
	}

	if (v_lnk_p->qec_27_select_cnt != 1)
	{
	    status = qed_u1_gen_interr(& i_qer_p->error);
	    return(status);
	}
    }

    if (v_lnk_p->qec_10_haves & QEC_11_LDB_DIFF_ARCH)
    {
	/* binary statistics data cannot be propagated for use due to 
	** different LDB architecture */

	tables_p->l16_9_stats[0] = 'N';		/* declare no statistics */
    }
    else if (!
	(
	(tables_p->l16_9_stats[0] == 'N')
	||
	(tables_p->l16_9_stats[0] == 'n')
	))
	v_lnk_p->qec_10_haves |= QEC_05_STATS;

    if (!
	(
	(tables_p->l16_10_indexes[0] == 'N')
	||
	(tables_p->l16_10_indexes[0] == 'n')
	))
	v_lnk_p->qec_10_haves |= QEC_02_INDEXES;

    /* 3.  set up tuple for insertion */

    l_obj = (u_i4)qed_u0_trimtail( ddl_p->qed_d1_obj_name, (u_i4)DB_OBJ_MAXNAME,
		tables_p->l16_1_tab_name);

    qed_u0_trimtail( ddl_p->qed_d2_obj_owner, (u_i4) DB_OWN_MAXNAME,
		tables_p->l16_2_tab_owner);

    STcopy(v_lnk_p->qec_24_cur_time, 
	    tables_p->l16_3_cre_date);
    STcopy(v_lnk_p->qec_24_cur_time, 
	    tables_p->l16_4_alt_date);

    if (tabinfo_p->dd_t3_tab_type == DD_2OBJ_TABLE)
	tables_p->l16_5_tab_type[0] = 'T';	/* local table */
    else if (tabinfo_p->dd_t3_tab_type == DD_3OBJ_VIEW)
	tables_p->l16_5_tab_type[0] = 'V';	/* local view */
    else if (tabinfo_p->dd_t3_tab_type == DD_4OBJ_INDEX)
	tables_p->l16_5_tab_type[0] = 'I';	/* local index */
    else 
    {
	status = qed_u2_set_interr(E_QE0018_BAD_PARAM_IN_CB,
		    & i_qer_p->error);
	return(status);
    }
    tables_p->l16_5_tab_type[1] = EOS;		/* null terminate */

    if (ddl_p->qed_d8_obj_type == DD_1OBJ_LINK)
   	tables_p->l16_6_sub_type[0] = 'L';	/* DDB link */
    else if (ddl_p->qed_d8_obj_type == DD_2OBJ_TABLE
	     ||
	     ddl_p->qed_d8_obj_type == DD_3OBJ_VIEW)
	tables_p->l16_6_sub_type[0] = 'N';	/* DDB native */
    else
    {
	status = qed_u2_set_interr(E_QE0018_BAD_PARAM_IN_CB,
		    & i_qer_p->error);
	return(status);
    }
    tables_p->l16_6_sub_type[1] = EOS;		/* null terminate */

    STcopy(IIQE_42_ing_60, tables_p->l16_7_version);

    if (dds_p->qes_d9_ctl_info & QES_05CTL_SYSCAT_USER)
    {
	char *ch2 = ddl_p->qed_d1_obj_name + CMbytecnt(ddl_p->qed_d1_obj_name);

	if( ( l_obj >= 2 ) &&
	    (CMcmpnocase(ddl_p->qed_d1_obj_name, "i") == 0 ) &&
	    (CMcmpnocase(ch2, "i") == 0 ))
	{
	    tables_p->l16_8_sys_use[0] = 'S';	/* system object */

	}
	else
	    tables_p->l16_8_sys_use[0] = 'U';	/* user object */
    }
    else
	tables_p->l16_8_sys_use[0] = 'U';	/* user object */
    tables_p->l16_8_sys_use[1] = EOS;		/* null terminate */

    if (! (v_lnk_p->qec_10_haves & QEC_03_INGRES) )
    {
	/* index information NOT propagated for gateways */
	tables_p->l16_10_indexes[0] = 'N';	/* N */
	tables_p->l16_10_indexes[1] = EOS;	/* null terminate */
    }
    tables_p->l16_23_integrities[0] = 'N';	/* always N */
    tables_p->l16_23_integrities[1] = EOS;	/* null terminate */

    tables_p->l16_24_permits[0] = 'N';		/* always N */
    tables_p->l16_24_permits[1] = EOS;	/* null terminate */

    if (tabinfo_p->dd_t3_tab_type == DD_4OBJ_INDEX)
	tables_p->l16_25_all_to_all[0] = 'N';	/* always N if an index */
    else
	tables_p->l16_25_all_to_all[0] = 'Y';	/* always Y otherwise */
    tables_p->l16_25_all_to_all[1] = EOS;	/* null terminate */

    /* 4.  insert into IIDD_TABLES */

    ins_p->qeq_c1_can_id = INS_631_DD_TABLES;	
    ins_p->qeq_c3_ptr_u.l16_tables_p = tables_p;	
    ins_p->qeq_c4_ldb_p = cdb_p;
    status = qel_i1_insert(i_qer_p, v_lnk_p);

    return(status);
}