void ConditionEncoder::TransformINsOnLookup()
{
	MEASURE_FET("ConditionEncoder::TransformINsOnLookup(...)");
	static MIIterator mid(0);
	ValueSet valset;
    RCBString s;
    for(int i = 0; i < attr->dic->CountOfUniqueValues(); i++) {
        s = attr->dic->GetRealValue(i);
        if((static_cast<MultiValColumn*>(desc->val1.vc))->Contains(mid, s) == true)
			valset.Add64(i);
    }
    in_type = ColumnType(RC_NUM);
	desc->val1.vc = new InSetColumn(in_type, NULL, valset);
	desc->val1.vc_id = desc->table->AddVirtColumn(desc->val1.vc);
	if(static_cast<InSetColumn&>(*desc->val1.vc).IsEmpty(mid)) {
		if(desc->op == O_IN)
			desc->op = O_FALSE;
		else
			desc->op = O_NOT_NULL;
	}
}
void ConditionEncoder::LookupExpressionTransformation()
{
	MEASURE_FET("ConditionEncoder::LookupExpressionTransformation(...)");
	ExpressionColumn* vcec = dynamic_cast<ExpressionColumn*>(desc->attr.vc);
	VirtualColumnBase::VarMap col_desc = vcec->GetLookupCoordinates();
	MILookupIterator mit;
	mit.Set(NULL_VALUE_64);
	desc->encoded = false;
	bool null_positive = desc->CheckCondition(mit);
	ValueSet valset;
	in_type = ColumnType(RC_NUM);
	int code = 0;
	do {
		mit.Set(code);
		if(desc->CheckCondition(mit)) {
			if(mit.IsValid())
				valset.Add64(code);
		}
		code++;
	} while(mit.IsValid());

	if(!null_positive) {
		PhysicalColumn* col = col_desc.GetTabPtr()->GetColumn(col_desc.col_ndx);
		desc->attr.vc = new SingleColumn(col, vcec->GetMultiIndex(), col_desc.var.tab, col_desc.col_ndx, col_desc.GetTabPtr().get(), vcec->GetDim());
		desc->attr.vc_id = desc->table->AddVirtColumn(desc->attr.vc);
		desc->op = O_IN;
		desc->val1.vc = new InSetColumn(in_type, NULL, valset);
		desc->val1.vc_id = desc->table->AddVirtColumn(desc->val1.vc);
		desc->encoded = true;
	} else if(valset.IsEmpty()) {
		PhysicalColumn* col = col_desc.GetTabPtr()->GetColumn(col_desc.col_ndx);
		desc->attr.vc = new SingleColumn(col, vcec->GetMultiIndex(), col_desc.var.tab, col_desc.col_ndx, col_desc.GetTabPtr().get(), vcec->GetDim());
		desc->attr.vc_id = desc->table->AddVirtColumn(desc->attr.vc);
		desc->op = O_IS_NULL;
		desc->encoded = true;
	} else {	// both nulls and not-nulls are positive - no single operator possible
		// do not encode
		desc->encoded = false;
	}
}
void ConditionEncoder::TransformLIKEsIntoINsOnLookup()
{
	MEASURE_FET("ConditionEncoder::TransformLIKEsIntoINsOnLookup(...)");
	BHASSERT_WITH_NO_PERFORMANCE_IMPACT(attr->Type().IsLookup());

	if(desc->op == O_LIKE)
		desc->op = O_IN;
	else
		desc->op = O_NOT_IN;

	ValueSet valset;
	static MIIterator mid(0);
	in_type = ColumnType(RC_NUM);
	RCBString pattern;
	desc->val1.vc->GetValueString(pattern, mid);
	for(int i = 0; i < attr->dic->CountOfUniqueValues(); i++) {
		int res;
		if(RequiresUTFConversions(desc->GetCollation())) {
			RCBString s = attr->dic->GetRealValue(i);
			res = ! wildcmp(desc->GetCollation(), s.val, s.val + s.len,
					pattern.val, pattern.val + pattern.len,
					desc->like_esc, '_', '%');
		} else
			res = attr->dic->GetRealValue(i).Like(pattern, desc->like_esc);
		if(res)
			valset.Add64(i);
	}
	desc->val1.vc = new InSetColumn(in_type, NULL, valset);
	desc->val1.vc_id = desc->table->AddVirtColumn(desc->val1.vc);
	if(static_cast<InSetColumn&>(*desc->val1.vc).IsEmpty(mid)) {
		if(desc->op == O_IN)
			desc->op = O_FALSE;
		else
			desc->op = O_NOT_NULL;
	}
}