fis-gtm/sr_port/gvzwr_var.c

226 lines
6.5 KiB
C

/****************************************************************
* *
* Copyright 2001, 2011 Fidelity Information Services, Inc *
* *
* This source code contains the intellectual property *
* of its copyright holder(s), and is made available *
* under a license. If you do not know the terms of *
* the license, please stop and do not read further. *
* *
****************************************************************/
#include "mdef.h"
#include "gdsroot.h"
#include "gtm_facility.h"
#include "fileinfo.h"
#include "gdsbt.h"
#include "gdsfhead.h"
#include "zwrite.h"
#include "op.h"
#include "outofband.h"
#include "numcmp.h"
#include "patcode.h"
#include "sgnl.h"
#include "mvalconv.h"
#include "follow.h"
#include "gtm_string.h"
#define eb_less(u, v) (numcmp(u, v) < 0)
GBLREF gv_key *gv_currkey;
GBLREF gvzwrite_datablk *gvzwrite_block;
GBLREF int4 outofband;
GBLREF gd_region *gv_cur_region;
LITREF mval literal_null;
void gvzwr_var(uint4 data, int4 n)
{
mval mv, subdata;
unsigned short end, prev, end1, prev1;
bool save_gv_last_subsc_null;
boolean_t do_lev;
char seen_null;
zwr_sub_lst *zwr_sub;
int loop_condition = 1;
DCL_THREADGBL_ACCESS;
SETUP_THREADGBL_ACCESS;
if (outofband)
outofband_action(FALSE);
zwr_sub = (zwr_sub_lst *)gvzwrite_block->sub;
if ((0 == gvzwrite_block->subsc_count) && (0 == n))
zwr_sub->subsc_list[n].subsc_type = ZWRITE_ASTERISK;
if ((1 == data || 11 == data) &&
(!gvzwrite_block->subsc_count || (ZWRITE_ASTERISK == zwr_sub->subsc_list[n].subsc_type) ||
(n && !(gvzwrite_block->mask >> n))))
gvzwr_out();
if ((1 >= data) || (gvzwrite_block->subsc_count && (n >= gvzwrite_block->subsc_count)
&& (ZWRITE_ASTERISK != zwr_sub->subsc_list[gvzwrite_block->subsc_count - 1].subsc_type)))
return;
assert(1 < data);
end = gv_currkey->end;
prev = gv_currkey->prev;
if ((n < gvzwrite_block->subsc_count) && (ZWRITE_VAL == zwr_sub->subsc_list[n].subsc_type))
{
mval2subsc(zwr_sub->subsc_list[n].first, gv_currkey);
op_gvdata(&subdata);
if (MV_FORCE_INTD(&subdata) && ((10 != (int4)MV_FORCE_INTD(&subdata)) || n < gvzwrite_block->subsc_count - 1))
{
save_gv_last_subsc_null = TREF(gv_last_subsc_null);
gvzwr_var((int4)MV_FORCE_INTD(&subdata), n + 1);
TREF(gv_last_subsc_null) = save_gv_last_subsc_null;
} else if (gvzwrite_block->fixed)
sgnl_gvundef();
} else
{
seen_null = 0;
if (n < gvzwrite_block->subsc_count
&& zwr_sub->subsc_list[n].first
&& ZWRITE_PATTERN != zwr_sub->subsc_list[n].subsc_type)
{
mv = *zwr_sub->subsc_list[n].first;
mval2subsc(&mv, gv_currkey);
if ((mv.mvtype & MV_STR) && !mv.str.len)
seen_null = 1;
op_gvdata(&subdata);
} else
{
mval2subsc((mval *)&literal_null, gv_currkey);
TREF(gv_last_subsc_null) = TRUE;
if (0 == gv_cur_region->std_null_coll)
{
op_gvorder(&mv); /* This will return the first subscript */
if (0 == mv.str.len)
{
if (NEVER == gv_cur_region->null_subs || seen_null)
loop_condition = 0;
else
{
seen_null = 1; /* set flag to indicate processing null sub */
op_gvnaked(VARLSTCNT(1) &mv);
op_gvdata(&subdata);
if (!MV_FORCE_INTD(&subdata))
loop_condition = 0;
}
} else
{
op_gvnaked(VARLSTCNT(1) &mv);
op_gvdata(&subdata);
}
} else /* for standard null collation */
{
/* determine whether $data(^gbl("") == 1 or 11,
if yes, first process that
*/
if (NEVER == gv_cur_region->null_subs)
{
op_gvorder(&mv);
assert(0 != mv.str.len); /* We are looking for the first subscript at a given level and so,
we do not expect to have hit at the end of the list */
op_gvnaked(VARLSTCNT(1) &mv);
op_gvdata(&subdata);
} else
{
op_gvdata(&subdata);
if (MV_FORCE_INTD(&subdata))
seen_null = 1;
}
}
}
while (loop_condition)
{
do_lev = (MV_FORCE_INTD(&subdata) ? TRUE : FALSE);
if (n < gvzwrite_block->subsc_count)
{
if (ZWRITE_PATTERN == zwr_sub->subsc_list[n].subsc_type)
{
if (!do_pattern(&mv, zwr_sub->subsc_list[n].first))
do_lev = FALSE;
} else if (ZWRITE_ALL != zwr_sub->subsc_list[n].subsc_type)
{
if (do_lev && zwr_sub->subsc_list[n].first)
{
if (MV_IS_CANONICAL(&mv))
{
if (!MV_IS_CANONICAL(zwr_sub->subsc_list[n].first)
|| eb_less(&mv, zwr_sub->subsc_list[n].first))
do_lev = FALSE;
} else
{
if (!MV_IS_CANONICAL(zwr_sub->subsc_list[n].first)
&& (!follow(&mv, zwr_sub->subsc_list[n].first) &&
(mv.str.len != zwr_sub->subsc_list[n].first->str.len ||
memcmp(mv.str.addr,
zwr_sub->subsc_list[n].first->str.addr,
mv.str.len))))
do_lev = FALSE;
}
}
if (do_lev && zwr_sub->subsc_list[n].second)
{
if (MV_IS_CANONICAL(&mv))
{
if (MV_IS_CANONICAL(zwr_sub->subsc_list[n].second)
&& eb_less(zwr_sub->subsc_list[n].second, &mv))
do_lev = FALSE;
} else
{
if (MV_IS_CANONICAL(zwr_sub->subsc_list[n].second)
|| (!follow(zwr_sub->subsc_list[n].second, &mv) &&
(mv.str.len != zwr_sub->subsc_list[n].second->str.len ||
memcmp(mv.str.addr,
zwr_sub->subsc_list[n].second->str.addr,
mv.str.len))))
do_lev = FALSE;
}
if (!do_lev)
break;
}
}
}
if (do_lev)
{
end1 = gv_currkey->end;
prev1 = gv_currkey->prev;
save_gv_last_subsc_null = TREF(gv_last_subsc_null);
gvzwr_var((int4)MV_FORCE_INTD(&subdata), n + 1);
TREF(gv_last_subsc_null) = save_gv_last_subsc_null;
gv_currkey->end = end1;
gv_currkey->prev = prev1;
gv_currkey->base[end1] = 0;
}
if (1 == seen_null)
{
assert(TREF(gv_last_subsc_null));
TREF(gv_last_subsc_null) = FALSE;
seen_null = 2; /* set flag to indicate null sub processed */
}
op_gvorder(&mv);
/* When null subscript is in the middle,
but with standard collation null subscripts can not be in the middle, so don't need to be worried
*/
if (0 == mv.str.len)
{
if (NEVER == gv_cur_region->null_subs || seen_null || gv_cur_region->std_null_coll)
break;
else
{
seen_null = 1; /* set flag to indicate processing null sub */
op_gvnaked(VARLSTCNT(1) &mv);
op_gvdata(&subdata);
if (!MV_FORCE_INTD(&subdata))
break;
}
} else
{
op_gvnaked(VARLSTCNT(1) &mv);
op_gvdata(&subdata);
}
}
}
gv_currkey->end = end;
gv_currkey->prev = prev;
gv_currkey->base[end] = 0;
}