226 lines
6.5 KiB
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;
|
|
}
|