Beispiel #1
0
VOID
r_rep_load ()
{
	char    *outname;
	char    *tempname;


	/* start of routine */

	r_open_db();		/* open database. If not there, abort */

	STtrmwhite(En_report);

	/* start object-oriented facility for retrieving reports */
	IIOOinit((OO_OBJECT **)NULL);

	En_rid = -1;

	/* set up report environment. */
	if (St_style==RS_NULL && (St_ispec || r_env_set()))
	{	/* report found.  Read in report specifications */
		if (!St_silent)
		{
			SIprintf(ERget(F_RW0005_Reading_report_spec));
			SIflush(stdout);
		}

		r_rco_set();	/* read in the RCOMMANDS table into core */
	}
	else
	{	/* no report found.  Use report name */
		if (St_repspec)
		{	/* error because report does not exist */
			r_error(0x3F7, FATAL, En_report, NULL);
		}
		En_rtype = RT_DEFAULT;
		En_ferslv.name = En_report;
		if  ((En_ferslv.name_dest = (char *)FEreqmem((u_i4)Rst4_tag,
		     (u_i4)(FE_MAXNAME+1),TRUE,(STATUS *)NULL)) == NULL)
		{
			IIUGbmaBadMemoryAllocation(
					ERx("r_rep_loadld - name_dest"));
		}

		if  ((En_ferslv.owner_dest = (char *)FEreqmem((u_i4)Rst4_tag,
		     (u_i4)(FE_MAXNAME+1),TRUE,(STATUS *)NULL)) == NULL)
		{
			IIUGbmaBadMemoryAllocation(
					ERx("r_rep_loadld - owner_dest"));
		}
		/*
		** If the server supports delimited identifiers, then
		** ensure that .DELIMID is enabled since we're doing a report
		** based upon a table, and it may require such services.
		*/
		if  (IIUIdlmcase() != UI_UNDEFCASE)
		{
			St_xns_given = TRUE;
		}
	}

	/*
	** set up (and maybe prompt for) declared variables
	*/
	r_dcl_set(TRUE);

        if ((En_qlang == FEDMLSQL) && (IIUIdbdata()->firstAutoCom == FALSE))
	{
		IIUIautocommit(UI_AC_OFF);
	}

	if( r_sc_qry(Ptr_set_top) == FAIL )
	{
		return;
	}
    
	IIUIdlmcase();          /* Hack for bug 96801 ingcbt198 */

	if(!r_chk_dat())		/* check for a valid data relation */
	{
		return;
	}


	if( !r_sendqry())/* send the query to the backend */
	{
		return;
	}
	

	if (!r_att_dflt())	/* set up ATT structures for each */
	{			/* attribute in the data relation */
		return;
	}


	if (En_rtype == RT_DEFAULT)
	{	/* set up the default report */
		if (!St_silent)
		{
			SIprintf(ERget(F_RW0006_Setting_up_default));
			SIflush(stdout);
		}

		/* Set up first column as a sort column */

		if  (!r_m_dsort())
		{
			r_error(0x416,NONFATAL,NULL);
			return;
		}
	}

	if (!r_srt_set())		/* set up the SORT data structures */
	{	/* bad RSORT */
		r_error(0x0C, FATAL, NULL);
	}
	/* set up the BRK data structures
	** for each sort attribute with a
	** RACTION tuple defined for it
	*/
	if( !r_brk_set())	
	{
		return;
	}


	/* 
	** If there is a .PAGEWIDTH command and no -l flag has been specified 
	** on the commandline, then reset En_lmax. (The -l flag overrides the 
	** .PAGEWIDTH command). (#129, #588)
	*/
        if( STlength(En_pg_width) > 0 && !St_lspec)
	{
		/* If the pagewidth value is preceded by
		* a dollar, evaluate it as a parameter
		*/
		r_g_set(En_pg_width);
		if( r_g_skip() == TK_DOLLAR )
		{
			CMnext(Tokchar);
			outname = r_g_name();
			if( (tempname = r_par_get(outname)) == NULL )
			{
				r_error(0x3F0, FATAL, outname, NULL);
			}
			STcopy(tempname, En_pg_width);
		}
		/* need to convert to a number and set it to En_lmax */
		if (CVan(En_pg_width, &En_lmax) != OK)
		{
			/* Unable to convert so ignore input */
			r_error(0x403, NONFATAL, outname, NULL);
		}
	}
		
	if (En_rtype == RT_DEFAULT)
	{	/* set up default report */
		r_m_rprt();
	}
	else
	{
		Tcmd_tag = FEbegintag();
		r_tcmd_set();		/* set up the tcmd data structures */
		FEendtag();
	}


	r_lnk_agg();		/* set up the CLR and OP structures for
				** fast processing of aggregates.
				*/

	return;
}
Beispiel #2
0
void
rf_att_dflt(i4 NumRels, char *RelList[])
{

    FE_ATT_QBLK        qblk;
    FE_ATT_INFO        attinfo;
    FE_REL_INFO        relinfo;
    register ATTRIB      id;
    i4         	       i = 0;
    bool               RepeatedField;
    char 	       ColName [FE_MAXNAME + 1];
    i4		       ins = 0;
    FE_RSLV_NAME	*rfa_ferslv[MQ_MAXRELS];
    RFCOLDESC		*coldesc;
    ATT			*attptr;
    char		*cname;
    ATTRIB		did;
    i4			real_cols;
    char		dsply_name[(FE_UNRML_MAXNAME + 1)];


    /*
    **  If the user went through the choose columns path, we will
    **  use that information to create the structures since we
    **  alredy have all the needed information.
    */
    if (IIRFcccount != 0)
    {
	En_n_attribs = IIRFcccount;
	real_cols = IIRFcccount - IIRFcdcount;

	/* Allocate memory for the ATT array. */
	if ((Ptr_att_top = (ATT *)FEreqmem((u_i4)Rst4_tag,
		(u_i4)(IIRFcccount*(sizeof(ATT))), TRUE, 
		(STATUS *)NULL)) == NULL)
	{
		IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - Ptr_att_top"));
	}

	/*
	**  Step through the set of column names.  Deleted ones are
	**  placed at the end of the array.  We need to keep them
	**  around so that the user can add them back in the layout
	**  frame.
	*/
	for (i = 0, id = 0, did = real_cols, coldesc = IIRFcollist;
		i < IIRFcccount; i++, coldesc++)
	{
		if (coldesc->deleted)
		{
			attptr = &(Ptr_att_top[did++]);
			attptr->pre_deleted = TRUE;
		}
		else
		{
			attptr = &(Ptr_att_top[id++]);
		}
		cname = coldesc->name;
		attptr->att_name = FEtsalloc(Rst4_tag, cname);

		/* check if attribute name is a keyword */

		if (!St_silent && (r_gt_pcode(cname) != PC_ERROR ||
			r_gt_wcode(cname) != A_ERROR ||
			r_gt_vcode(cname) != VC_NONE ||
			r_gt_cagg(cname) ||
			STcompare(cname, NAM_REPORT) == 0 ||
			STcompare(cname, NAM_PAGE) == 0 ||
			STcompare(cname, NAM_DETAIL) == 0))
		{
			IIUGmsg(ERget(S_RF0047_Column_name_keyword), 
				(bool) FALSE, 1, cname);
		}

		/* set up the data type field */
		attptr->att_value.db_datatype = coldesc->datatype;
		attptr->att_prev_val.db_datatype = coldesc->datatype;
		attptr->att_value.db_length = coldesc->length;
		attptr->att_prev_val.db_length = coldesc->length;
		attptr->att_value.db_prec = coldesc->prec;
		attptr->att_prev_val.db_prec = coldesc->prec;
    
		/*
		** Do not allocate value buffers for un-supported datatypes.
		** We already let the user know that they're being ignored
		** when we passed through ChooseColumns, so don't do it again!
		*/
		if  (!IIAFfedatatype(&attptr->att_value))
		{
			attptr->att_value.db_data = (PTR)NULL;
			attptr->att_prev_val.db_data = (PTR)NULL;
		}
		else
		{
			if ((attptr->att_value.db_data =
				(PTR)FEreqmem((u_i4)Rst4_tag,
				(u_i4)(attptr->att_value.db_length),
				TRUE, (STATUS *)NULL)) == NULL)
			{
				IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - db_data"));
			}
			if ((attptr->att_prev_val.db_data = 
				(PTR)FEreqmem((u_i4)Rst4_tag,
				(u_i4)(attptr->att_prev_val.db_length),
				TRUE, (STATUS *)NULL)) == NULL)
			{
				IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - prev db_data"));
			}
		}

		/* flag to indicate when done */
		attptr->att_position = 0;
		attptr->att_lac = NULL;
	}

	return;
    }


    /* 
    ** determine number of attributes in base table: 
    */
    for (i = 0; i < NumRels; i ++)
    {
	/*
	** Decompose any owner.tablename, validate the components,
	** and normalize them for later use.
	*/
	if  ((rfa_ferslv[i] = (FE_RSLV_NAME *)MEreqmem((u_i4)0,
		(u_i4)sizeof(FE_RSLV_NAME),TRUE,
		(STATUS *)NULL)) == (FE_RSLV_NAME *)NULL)
	{
		IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - rfa_ferslv"));
	}
	if  ((rfa_ferslv[i]->name_dest = (char *)MEreqmem((u_i4)0,
		(u_i4)(FE_UNRML_MAXNAME+1),TRUE,(STATUS *)NULL)) == NULL)
	{
		IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - name_dest"));
	}

	if  ((rfa_ferslv[i]->owner_dest = (char *)MEreqmem((u_i4)0,
		(u_i4)(FE_UNRML_MAXNAME+1),TRUE,(STATUS *)NULL)) == NULL)
	{
		IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - owner_dest"));
	}
	rfa_ferslv[i]->name = RelList[i];
	rfa_ferslv[i]->is_nrml = FALSE;
	FE_decompose(rfa_ferslv[i]);
	if  ((rfa_ferslv[i]->owner_spec) &&
	     (((STcompare(IIUIcsl_CommonSQLLevel(),UI_LEVEL_65) < 0)
	     && (IIUIdcd_dist() == FALSE)
	     || IIUIdcd_dist() == TRUE && (STcompare(IIUIcsl_CommonSQLLevel(), 
	     UI_LEVEL_61) < 0))))
	{
		continue;
	}
	if  ((IIUGdlm_ChkdlmBEobject(rfa_ferslv[i]->name_dest,
				    rfa_ferslv[i]->name_dest,
				    rfa_ferslv[i]->is_nrml) == UI_BOGUS_ID) ||
	     ((rfa_ferslv[i]->owner_spec) &&
	      ((IIUGdlm_ChkdlmBEobject(rfa_ferslv[i]->owner_dest,
				      rfa_ferslv[i]->owner_dest,
				      rfa_ferslv[i]->is_nrml) == UI_BOGUS_ID) &&
	      STcompare(rfa_ferslv[i]->owner_dest, UI_FE_CAT_ID_65))))
	{
		continue;
	}
	if  (FE_resolve(rfa_ferslv[i],rfa_ferslv[i]->name_dest,
			rfa_ferslv[i]->owner_dest))
	{
		En_n_attribs += FEnumatts(rfa_ferslv[i]->name_dest,
					  rfa_ferslv[i]->owner_dest);
	}
    }

    /* 
    ** Allocate array of ATT structures:
    */
    if ((Ptr_att_top = (ATT *)FEreqmem((u_i4)Rst4_tag,
        (u_i4)(En_n_attribs*(sizeof(ATT))), TRUE, 
        (STATUS *)NULL)) == NULL)
    {
        IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - Ptr_att_top"));
    }

    /*
    ** For each relation fill out the ATT structures:
    */
    id = 0;

    if (En_SrcTyp == JDRepSrc)
	_VOID_ r_JDMaintTabList(JD_TAB_INIT_INS_CNT, NULL, NULL, NULL, NULL);

    for (i = 0; i < NumRels; i ++)
    {
        /* 
        ** open access to base table 
        */

	/* 
	** Fill out relinfo with table information, including table owner.
	*/
	FErel_ffetch(rfa_ferslv[i]->name_dest,rfa_ferslv[i]->owner_dest,
		     &relinfo);
	MEfree((PTR)rfa_ferslv[i]->name_dest);
	MEfree((PTR)rfa_ferslv[i]->owner_dest);
	MEfree((PTR)rfa_ferslv[i]);
       	FEatt_fopen(&qblk, &relinfo);

    	if (En_SrcTyp == JDRepSrc)
	    _VOID_ r_JDMaintTabList(JD_TAB_TAB_ADV_INS_CNT, NULL, 
			relinfo.name, relinfo.owner, &ins);

        /* 
        ** For each attribute in table, fill ATT structure 
        ** (make sure no DB access will take place in this loop!) 
        */
        while (FEatt_fetch(&qblk, &attinfo) == OK)
        {
            register ATT    *r_att;
            register ATTRIB chk_id;
            register char    *attname;

            attname = attinfo.column_name;

            /*
            ** Check for duplicate column names. If found one, and 
	    ** the source of data is not a JoinDef we have a problem,
	    ** Bug #5952:
            */
            RepeatedField = FALSE;
	    chk_id = id - 1;
	    while ((--chk_id >= 0) && (!RepeatedField))
	    {
                register ATT *chk_p = &(Ptr_att_top[chk_id]);
                if (STcompare(chk_p->att_name, attname) == 0)
                    RepeatedField = TRUE;
            }

            if ((RepeatedField) && (En_SrcTyp == TabRepSrc))
	    {
            	r_error(0x2C8, FATAL, attname, NULL);
	    }

	    /*
	    ** Make sure that if the source of data is a JoinDef 
	    ** the attribute is being used, and if it's being used 
	    ** in more than one table get the constructed name for 
	    ** it.  Be sure and include the owner in the table look-up!
	    */
	    if (En_SrcTyp == JDRepSrc)
	    {
		i4 cnt = 0;

		/*
		** If we can't find the field then it's not being used so 
		** skip it:
		*/
		if (!r_JDMaintAttrList(JD_ATT_GET_FIELD_CNT,
			r_JDTabNameToRv(relinfo.name, relinfo.owner, ins),
			attname, &cnt))
		   continue;

		
		if (cnt > 1)
		{
		  _VOID_ r_JDMaintAttrList(JD_ATT_GET_ATTR_NAME,
			r_JDTabNameToRv(relinfo.name, relinfo.owner, ins),
			attname, &ColName [0]);
		  attname = ColName;
		}
	    }

            r_att = &(Ptr_att_top[id++]);
            r_att->att_name = FEtsalloc(Rst4_tag, attname);
    
            /* check if attribute name is a keyword */
    
            if (!St_silent && (r_gt_pcode(attname) != PC_ERROR ||
                      r_gt_wcode(attname) != A_ERROR ||
                      r_gt_vcode(attname) != VC_NONE ||
                      r_gt_cagg(attname) ||
                      STcompare(attname, NAM_REPORT) == 0 ||
                      STcompare(attname, NAM_PAGE) == 0 ||
                      STcompare(attname, NAM_DETAIL) == 0))
            {
                IIUGmsg(ERget(S_RF0047_Column_name_keyword), 
                    (bool) FALSE, 1, attname);
            }

            /* set up the data type field */
            r_att->att_value.db_datatype = attinfo.adf_type;
            r_att->att_prev_val.db_datatype = attinfo.adf_type;
            r_att->att_value.db_length = attinfo.intern_length;
            r_att->att_prev_val.db_length = attinfo.intern_length;
            r_att->att_value.db_prec = attinfo.intern_prec;
            r_att->att_prev_val.db_prec = attinfo.intern_prec;
    
	    /*
	    ** Do not allocate value buffers for un-supported datatypes.
	    ** Let the user know that they're being ignored.
	    */
	    if  (!IIAFfedatatype(&r_att->att_value))
	    {
		_VOID_ IIUGxri_id(&attinfo.column_name[0],
				  &dsply_name[0]);
		IIUGerr(E_RW1414_ignored_attrib,
			UG_ERR_ERROR,1,&dsply_name[0]);
		r_att->att_value.db_data = (PTR)NULL;
		r_att->att_prev_val.db_data = (PTR)NULL;
	    }
	    else
	    {
		if ((r_att->att_value.db_data =
				(PTR)FEreqmem((u_i4)Rst4_tag,
					(u_i4)(r_att->att_value.db_length),
					 TRUE, (STATUS *)NULL)) == NULL)
		{
		    IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - db_data"));
		}
		if ((r_att->att_prev_val.db_data = 
				(PTR)FEreqmem((u_i4)Rst4_tag,
					(u_i4)(r_att->att_prev_val.db_length),
					TRUE, (STATUS *)NULL)) == NULL)
		{
		    IIUGbmaBadMemoryAllocation(ERx("rf_att_dflt - prev db_data"));
		}
	    }

            r_att->att_position = 0;    /* flag to indicate when done */
            r_att->att_lac = NULL;
        }
        FEatt_close(&qblk);

    } /* for */

    /*
    ** Just in case if we have skipped any attributes, 
    ** we're leaking memory though:  Note that unsupported
    ** datatypes will not be reflected as skipped as far as the
    ** id count is concerned!
    */
    En_n_attribs = id;

    return;

}
Beispiel #3
0
/*{
** Name:	IIgetquery - Get query spec for field and process it.
**
** Description:
**	Given a field in a form, get the query specification for that
**	field and process it by calling FDrngchk().  If the field
**	is a table field, then process the passed in column for the
**	current row.  The current row is defined by the row that
**	is currently being unloaded in an "unloadtable" loop.
**
**	DML compatibility level is passed in and we assume that we will
**	be building the query, not just simply doing a validation
**	check.  Fields are assumed to be not display only.  The
**	DB_DATA_VALUE that is passed to FDrngchk() must be READ
**	ONLY to FDrngchk() and FDrngchk() must copy the value
**	if it wants to use it later on.
**
**	The current code is designed not to work with range query
**	buffers at the moment and only allows ONE qualification
**	per field.  When the switch to use range query
**	buffers is made, the code below (as well as some code in
**	FT) must be changed to call FTgetdisp().  Also, the use
**	of an "unloadtable" loop is invalid at this point and
**	another mechanism must be used to unload the range query
**	buffers for a table field.
**
**	Yes, the code below is looking at the forms structures
**	but it is only until we go to range query buffers.
**
** Inputs:
**	form		{char *}  Name of form containing field.
**	field		{char *}  Name of field on which to operate.
**	column		{char *}  Name of column if field is a table field.
**	tblname		{char *}  Name of database table to pass to FDrngchk().
**	dml_level	{nat}  DML compatibility level passed to 'FDrngchk()':
**					UI_DML_QUEL
**					UI_DML_SQL
**					UI_DML_GTWSQL
**	att		{char *}  Name of attribute in database table to pass
**				to FDrngchk().
**	prefix		{char *}  Special information to be passed
**				to FDrngchk().
**	func		{STATUS (*)()}  Function reference to pass
**				to FDrngchk().
**	data		{PTR}  Parameter to be passed to "func" by FDrnghck().
**
** Returns:
**	{STATUS}  OK	If everything worked.
**		  FAIL	If something went wrong.
**
** History:
**	06/09/87 (dkh) - Initial version.
**	08/25/88 (jhw) - Fixed Jup bug #3161.  Allow DISPONLY fields to
**				be qualified.
**      3/21/91 (elein)         (b35574) Add FALSE parameter to call to
**                              fmt_multi. TRUE is used internally for boxed
**                              messages only.  They need to have control
**                              characters suppressed.
*/
STATUS
IIgetquery (char *form, char *field, char *column, char *tblname,
	i4 dml_level, char *attr, char *prefix, STATUS (*func)(), PTR data )
{
	RUNFRM		*runf;
	FIELD		*fld;
	DB_DATA_VALUE	*dispdbv;
	FLDVAL		*val;
	STATUS		stat;
	bool		nonseq;
	DB_DATA_VALUE	ldbv;
	TBLFLD		*tbl;
	FLDCOL		*col;
	DB_TEXT_STRING	*text;
	DB_TEXT_STRING	*otext;
	ADF_CB		*ladfcb;
	FMT		*cfmt;
	i4		oper;
	char		*opchar;
	i4		qrycnt;
	DB_DATA_VALUE	valdbv;
	i4		rows = 0;
	i4		columns = 0;
	bool		reversed;
	i4		len;
	i4		cursize;
	i4		i;
	u_char		*c;
	u_char		*end;


	/*
	**  Do various checks on existence of form, field, etc.
	**  Return FAIL if something is missing.  Assume that
	**  we are being called from 'C', so no need to call
	**  IIstrconv().
	*/
	runf = ( form == NULL || *form == EOS ) ? IIstkfrm
			: RTfindfrm(form);
	if ( runf == NULL )
	{
		return FAIL;
	}

	/*
	**  Find field in the form, return FAIL if field does not exist.
	**  (Allow DISPONLY fields to be qualified, however.)
	*/
	if ( (fld = FDfndfld(runf->fdrunfrm, field, &nonseq)) == NULL )
	{
		IIFDerror( GFFLNF, 1, field );
		return FAIL;
	}

	ladfcb = FEadfcb();

	if ( (stat = FDfmtget(runf->fdrunfrm, field, column, 0, &cfmt)) != OK )
	{
	    return(stat);
	}
	if ( cfmt == NULL )
	{
	    return FAIL;
	}
	_VOID_ fmt_isreversed(ladfcb, cfmt, &reversed);

	if (qtag == 0)
	{
	    qtag = FEgettag();
	}

	if (fld->fltag == FREGULAR)
	{
		/*
		**  Just point to the simple field's display
		**  buffer.  It should be good.
		*/
		val = FDgetval(fld);
		dispdbv = val->fvdsdbv;
		if (reversed)
		{
		    /*
		    **  Find out information for formatting.
		    */
		    if (fmt_size(ladfcb, cfmt, val->fvdbv, &rows, &columns)
			!= OK)
		    {
			return(FAIL);
		    }

		    MEcopy((PTR) val->fvdsdbv, (u_i2) sizeof(DB_DATA_VALUE),
			(PTR) &valdbv);
		    if ((valdbv.db_data = FEreqmem(qtag,
			(u_i4)valdbv.db_length, TRUE, &stat)) == NULL)
		    {
			FEfree(qtag);
			return(FAIL);
		    }
		    text = (DB_TEXT_STRING *) valdbv.db_data;
		    otext = (DB_TEXT_STRING *) val->fvdsdbv->db_data;
		    cursize = text->db_t_count = otext->db_t_count;
		    MEcopy((PTR)otext->db_t_text, (u_i2)cursize,
			(PTR)text->db_t_text);

		    c = text->db_t_text;
		    len = rows * columns;

		    if (len > cursize)
		    {
			MEfill((u_i2)(len - cursize), (unsigned char)' ',
			    (PTR)(c + cursize));
			text->db_t_count = len;
		    }

		    for (i = 0; i < rows; i++)
		    {
			f_revrsbuf(columns, (bool)TRUE, c);
			c += columns;
		    }

		    /*
		    **  Need to trim trailing blanks at this point.
		    **  Don't need to use CM routines here, since Kanji
		    **  and reverse don't work together.
		    */
		    end = text->db_t_text;
		    c = end + text->db_t_count - 1;
		    while ( c >= end && *c-- == ' ' )
		    {
			--(text->db_t_count);
		    }

		    dispdbv = &valdbv;
		}
	}
	else
	{ /* a table field */
		FMT	scrfmt;		/* for scrolling columns */

		tbl = fld->fld_var.fltblfld;
		/*
		**  Need to get value and query operator from
		**  dataset and then convert into a LONG_TEXT
		**  struct for display.  First, check for
		**  existence of column.
		*/
		if ((col = FDfndcol(tbl, column)) == NULL)
		{
			return(FAIL);
		}

		/*
		**  Allocate local copies of column value and display
		**  buffers.
		*/
		val = tbl->tfwins + col->flhdr.fhseq;
			/* + ( 0 * tbl->tfcols ) */
		MEcopy((PTR) val->fvdbv, (u_i2) sizeof(DB_DATA_VALUE),
			(PTR) &valdbv);
		MEcopy((PTR) val->fvdsdbv, (u_i2) sizeof(DB_DATA_VALUE),
			(PTR) &ldbv);
		if ( (valdbv.db_data = FEreqmem(qtag, (u_i4)valdbv.db_length,
				TRUE, &stat)) == NULL ||
			(ldbv.db_data = FEreqmem(qtag, (u_i4)ldbv.db_length,
				TRUE, &stat)) == NULL )
		{
			FEfree(qtag);
			return FAIL;
		}

		if (IITBcieColIsEmpty(column))
		{
			text = (DB_TEXT_STRING *) ldbv.db_data;
			text->db_t_count = 0;
		}
		else
		{
			/*
			**  Get value for column from current row.
			**  Note that this is a direct call to internal routine
			**  and changes made must be done carefully.
			*/
			if ( !IItcogetio((i2 *) NULL, TRUE, DB_DBV_TYPE, 0,
				&valdbv, column) )
			{
				FEfree(qtag);
				return(FAIL);
			}

			/*
			**  Now get query operator.
			*/
			IIgetoper(1);
			if ( !IItcogetio((i2 *) NULL, TRUE, DB_INT_TYPE,
				sizeof(oper), &oper, column) )
			{
				FEfree(qtag);
				return(FAIL);
			}

			/*
			**  Format value.
			*/
			/*
			** If it's a scrolling column, make a format for all the
			** data, not just the fraction that can be displayed 
			** at once.
			*/
			if ((col->flhdr.fhd2flags & fdSCRLFD) != 0)
			{
				STRUCT_ASSIGN_MACRO(*cfmt, scrfmt);
				scrfmt.fmt_width = ldbv.db_length - 2;
				cfmt = &scrfmt;
			}

			/*
			**  Find out information for formatting.
			*/
			if (fmt_size(ladfcb, cfmt, &valdbv, &rows,
				&columns) != OK)
			{
				FEfree(qtag);
				return(FAIL);
			}

			/*
			**  Just format output if single line output.
			*/
			if (rows == 1)
			{
		    		if (fmt_format(ladfcb, cfmt, &valdbv, &ldbv,
					TRUE) != OK)
		    		{
					FEfree(qtag);
					return(FAIL);
		    		}
			}
			else
			{
				reg u_char	*dsptr;
				DB_TEXT_STRING	*ftext;
				PTR		buffer;
				DB_DATA_VALUE	wksp;
				i4		length = 0;

				wksp.db_datatype = DB_LTXT_TYPE;
				wksp.db_prec = 0;
				wksp.db_length = DB_CNTSIZE + columns;
				if ( (wksp.db_data = FEreqmem(qtag,
					(u_i4)wksp.db_length, TRUE, &stat))
					== NULL )
				{
					FEfree(qtag);
					return(FAIL);
				}
				fmt_workspace(ladfcb, cfmt, &valdbv, &length);
				if ( (buffer = FEreqmem(qtag, (u_i4)length,
					TRUE, &stat)) == NULL )
				{
					FEfree(qtag);
					return(FAIL);
				}

				/*
				**  Do multi-line output.
				*/

				IIfmt_init(ladfcb, cfmt, &valdbv, buffer);

				text = (DB_TEXT_STRING *) ldbv.db_data;
				text->db_t_count = 0;
				dsptr = text->db_t_text;
				ftext = (DB_TEXT_STRING *) wksp.db_data;
				for (;;)
				{
					reg i4		j;
					reg u_char	*fptr;
					i4		fcount;
					bool		more = FALSE;

					if (fmt_multi(ladfcb, cfmt, &valdbv,
						buffer, &wksp,&more,TRUE, FALSE)
					   != OK)
					{
						FEfree(qtag);
						return(FAIL);
					}

					if (!more)
					{
						break;
					}

					/*
					** put into fields display buffer.
					*/
					fcount = ftext->db_t_count;
					fptr = ftext->db_t_text;
					for (j = 0; j < fcount; j++)
					{
						*dsptr++ = *fptr++;
					}
					text->db_t_count += fcount;
				}
			}

			text = (DB_TEXT_STRING *) ldbv.db_data;

			if (reversed)
			{
		    		c = text->db_t_text;
		    		cursize = text->db_t_count;
		    		len = rows * columns;

		    		if (len > cursize)
		    		{
					MEfill((u_i2)(len - cursize),
						(unsigned char)' ',
			    			(PTR)(c + cursize));
					text->db_t_count = len;
		    		}

		    		for (i = 0; i < rows; i++)
		    		{
					f_revrsbuf(columns, (bool)TRUE, c);
					c += columns;
		    		}
			}

			/*
			**  Need to trim trailing blanks at this point.
			*/
			end = text->db_t_text;
			c = end + text->db_t_count - 1;
			while ( c >= end && *c-- == ' ' )
			{
		    		--(text->db_t_count);
			}

			/*
			**  Insert query operators up front.
			*/
			if ( oper != fdNOP && oper != fdEQ &&
			    (qrycnt = STlength(opchar = iiugOpRep(oper))) > 0 )
			{
				reg u_char	*dsptr;
				reg u_char	*head;
				reg i4		j;
				reg i4		cnt;

				head = text->db_t_text + text->db_t_count - 1;
				dsptr = head + qrycnt;
				cnt = text->db_t_count;
				for (j = 0; j < cnt; j++)
				{
					*dsptr-- = *head--;
				}
				text->db_t_text[0] = opchar[0];
				if (qrycnt == 2)
				{
					text->db_t_text[1] = opchar[1];
				}
				text->db_t_count += qrycnt;
			}
		}
		dispdbv = &ldbv;
	}

	stat = FDrngchk(runf->fdrunfrm, field, column, dispdbv, (bool) TRUE,
		tblname, attr, (bool) TRUE, dml_level, prefix, func, data);

	if (qtag != 0)
	{
		FEfree(qtag);
	}
	return stat;
}