Example #1
0
int 
exp_match_exp( sql_exp *e1, sql_exp *e2)
{
	if (exp_match(e1, e2))
		return 1;
	if (e1->type == e2->type) { 
		switch(e1->type) {
		case e_cmp:
			if (e1->flag == e2->flag && !is_complex_exp(e1->flag) &&
		            exp_match_exp(e1->l, e2->l) && 
			    exp_match_exp(e1->r, e2->r) && 
			    ((!e1->f && !e2->f) || exp_match_exp(e1->f, e2->f)))
				return 1;
			else if (e1->flag == e2->flag && e1->flag == cmp_or &&
		            exp_match_list(e1->l, e2->l) && 
			    exp_match_list(e1->r, e2->r))
				return 1;
			else if (e1->flag == e2->flag && 
				(e1->flag == cmp_in || e1->flag == cmp_notin) &&
		            exp_match_exp(e1->l, e2->l) && 
			    exp_match_list(e1->r, e2->r))
				return 1;
			break;
		case e_convert:
			if (!subtype_cmp(exp_totype(e1), exp_totype(e2)) &&
			    !subtype_cmp(exp_fromtype(e1), exp_fromtype(e2)) &&
			    exp_match_exp(e1->l, e2->l))
				return 1;
			break;
		case e_aggr:
			if (!subaggr_cmp(e1->f, e2->f) && /* equal aggregation*/
			    exp_match_list(e1->l, e2->l) && 
			    e1->flag == e2->flag)
				return 1;
			break;
		case e_func:
			if (!subfunc_cmp(e1->f, e2->f) && /* equal functions */
			    exp_match_list(e1->l, e2->l))
				return 1;
			break;
		case e_atom:
			if (e1->l && e2->l && !atom_cmp(e1->l, e2->l))
				return 1;
			break;
		default:
			break;
		}
	}
	return 0;
}
Example #2
0
/* cast atom a to type tp (success == 1, fail == 0) */
int 
atom_cast(atom *a, sql_subtype *tp) 
{
	sql_subtype *at = &a->tpe;

	if (!a->isnull) {
		if (subtype_cmp(at, tp) == 0) 
			return 1;
		/* need to do a cast, start simple is atom type a subtype of tp */
		if ((at->type->eclass == tp->type->eclass || 
		    (EC_VARCHAR(at->type->eclass) && EC_VARCHAR(tp->type->eclass))) &&
		    at->type->localtype == tp->type->localtype &&
		   (EC_TEMP(tp->type->eclass) || !tp->digits|| at->digits <= tp->digits) &&
		   (!tp->type->scale || at->scale == tp->scale)) {
			*at = *tp;
			return 1;
		}
		if (at->type->eclass == EC_NUM && tp->type->eclass == EC_NUM &&
	    	    at->type->localtype <= tp->type->localtype) {
			/* cast numerics */
			switch( tp->type->localtype) {
			case TYPE_bte:
				if (at->type->localtype != TYPE_bte) 
					return 0;
				break;
			case TYPE_sht:
				if (at->type->localtype == TYPE_bte) 
					a->data.val.shval = a->data.val.btval;
				else if (at->type->localtype != TYPE_sht)
					return 0;
				break;
			case TYPE_int:
#if SIZEOF_OID == SIZEOF_INT
			case TYPE_oid:
#endif
#if SIZEOF_WRD == SIZEOF_INT
			case TYPE_wrd:
#endif
				if (at->type->localtype == TYPE_bte) 
					a->data.val.ival = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.ival = a->data.val.shval;
				else if (at->type->localtype != TYPE_int) 
					return 0;
				break;
			case TYPE_lng:
#if SIZEOF_OID == SIZEOF_LNG
			case TYPE_oid:
#endif
#if SIZEOF_WRD == SIZEOF_LNG
			case TYPE_wrd:
#endif
				if (at->type->localtype == TYPE_bte) 
					a->data.val.lval = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.lval = a->data.val.shval;
				else if (at->type->localtype == TYPE_int) 
					a->data.val.lval = a->data.val.ival;
				else if (at->type->localtype != TYPE_lng) 
					return 0;
				break;
#ifdef HAVE_HGE
			case TYPE_hge:
				if (at->type->localtype == TYPE_bte) 
					a->data.val.hval = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.hval = a->data.val.shval;
				else if (at->type->localtype == TYPE_int) 
					a->data.val.hval = a->data.val.ival;
				else if (at->type->localtype == TYPE_lng) 
					a->data.val.hval = a->data.val.lval;
				else if (at->type->localtype != TYPE_hge) 
					return 0;
				break;
#endif
			default:
				return 0;
			}
			a->tpe = *tp;
			a->data.vtype = tp->type->localtype;
			return 1;
		}
		if (at->type->eclass == EC_DEC && tp->type->eclass == EC_DEC &&
		    at->type->localtype <= tp->type->localtype &&
		    at->digits <= tp->digits /* &&
		    at->scale <= tp->scale*/) {
#ifdef HAVE_HGE
			hge mul = 1, div = 0, rnd = 0;
#else
			lng mul = 1, div = 0, rnd = 0;
#endif
			/* cast numerics */
			switch( tp->type->localtype) {
			case TYPE_bte:
				if (at->type->localtype != TYPE_bte) 
					return 0;
				break;
			case TYPE_sht:
				if (at->type->localtype == TYPE_bte) 
					a->data.val.shval = a->data.val.btval;
				else if (at->type->localtype != TYPE_sht) 
					return 0;
				break;
			case TYPE_int:
#if SIZEOF_OID == SIZEOF_INT
			case TYPE_oid:
#endif
#if SIZEOF_WRD == SIZEOF_INT
			case TYPE_wrd:
#endif
				if (at->type->localtype == TYPE_bte) 
					a->data.val.ival = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.ival = a->data.val.shval;
				else if (at->type->localtype != TYPE_int) 
					return 0;
				break;
			case TYPE_lng:
#if SIZEOF_OID == SIZEOF_LNG
			case TYPE_oid:
#endif
#if SIZEOF_WRD == SIZEOF_LNG
			case TYPE_wrd:
#endif
				if (at->type->localtype == TYPE_bte) 
					a->data.val.lval = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.lval = a->data.val.shval;
				else if (at->type->localtype == TYPE_int) 
					a->data.val.lval = a->data.val.ival;
				else if (at->type->localtype != TYPE_lng) 
					return 0;
				break;
#ifdef HAVE_HGE
			case TYPE_hge:
				if (at->type->localtype == TYPE_bte) 
					a->data.val.hval = a->data.val.btval;
				else if (at->type->localtype == TYPE_sht) 
					a->data.val.hval = a->data.val.shval;
				else if (at->type->localtype == TYPE_int) 
					a->data.val.hval = a->data.val.ival;
				else if (at->type->localtype == TYPE_lng) 
					a->data.val.hval = a->data.val.lval;
				else if (at->type->localtype != TYPE_hge) 
					return 0;
				break;
#endif
			default:
				return 0;
			}
			/* fix scale */
			if (tp->scale >= at->scale) {
				mul = scales[tp->scale-at->scale];
			} else {
				/* only round when going to a lower scale */
				mul = scales[at->scale-tp->scale];
				rnd = mul>>1;
				div = 1;
			}
			a->tpe = *tp;
			a->data.vtype = tp->type->localtype;
#ifdef HAVE_HGE
			if (a->data.vtype == TYPE_hge) {
				a->data.val.hval += rnd;
				if (div)
					a->data.val.hval /= mul;
				else
					a->data.val.hval *= mul;
			} else if (a->data.vtype == TYPE_lng) {
				if (!div && ((hge) GDK_lng_min > (hge) a->data.val.lval * mul || (hge) a->data.val.lval * mul > (hge) GDK_lng_max))
					return 0;
				a->data.val.lval += (lng)rnd;
				if (div)
					a->data.val.lval /= (lng) mul;
				else
					a->data.val.lval *= (lng) mul;
			} else if (a->data.vtype == TYPE_int) {
				if (!div && ((hge) GDK_int_min > (hge) a->data.val.ival * mul || (hge) a->data.val.ival * mul > (hge) GDK_int_max))
					return 0;
				a->data.val.ival += (int)rnd;
				if (div)
					a->data.val.ival /= (int) mul;
				else
					a->data.val.ival *= (int) mul;
			} else if (a->data.vtype == TYPE_sht) {
				if (!div && ((hge) GDK_sht_min > (hge) a->data.val.shval * mul || (hge) a->data.val.shval * mul > (hge) GDK_sht_max))
					return 0;
				a->data.val.shval += (sht)rnd;
				if (div)
					a->data.val.shval /= (sht) mul;
				else
					a->data.val.shval *= (sht) mul;
			} else if (a->data.vtype == TYPE_bte) {
				if (!div && ((hge) GDK_bte_min > (hge) a->data.val.btval * mul || (hge) a->data.val.btval * mul > (hge) GDK_bte_max))
					return 0;
				a->data.val.btval += (bte)rnd;
				if (div)
					a->data.val.btval /= (bte) mul;
				else
					a->data.val.btval *= (bte) mul;
			}
#else
			if (a->data.vtype == TYPE_lng) {
				a->data.val.lval += rnd;
				if (div)
					a->data.val.lval /= mul;
				else
					a->data.val.lval *= mul;
			} else if (a->data.vtype == TYPE_int) {
				if (!div && ((lng) GDK_int_min > (lng) a->data.val.ival * mul || (lng) a->data.val.ival * mul > (lng) GDK_int_max))
					return 0;
				a->data.val.ival += (int)rnd;
				if (div)
					a->data.val.ival /= (int) mul;
				else
					a->data.val.ival *= (int) mul;
			} else if (a->data.vtype == TYPE_sht) {
				if (!div && ((lng) GDK_sht_min > (lng) a->data.val.shval * mul || (lng) a->data.val.shval * mul > (lng) GDK_sht_max))
					return 0;
				a->data.val.shval += (sht)rnd;
				if (div)
					a->data.val.shval /= (sht) mul;
				else
					a->data.val.shval *= (sht) mul;
			} else if (a->data.vtype == TYPE_bte) {
				if (!div && ((lng) GDK_bte_min > (lng) a->data.val.btval * mul || (lng) a->data.val.btval * mul > (lng) GDK_bte_max))
					return 0;
				a->data.val.btval += (bte)rnd;
				if (div)
					a->data.val.btval /= (bte) mul;
				else
					a->data.val.btval *= (bte) mul;
			}
#endif
			return 1;
		}
		/* truncating decimals */
		if (at->type->eclass == EC_DEC && tp->type->eclass == EC_DEC &&
		    at->type->localtype >= tp->type->localtype &&
		    at->digits >= tp->digits && 
			(at->digits - tp->digits) == (at->scale - tp->scale)) {
#ifdef HAVE_HGE
			hge mul = 1, rnd = 0, val = 0;
#else
			lng mul = 1, rnd = 0, val = 0;
#endif

			/* fix scale */

			/* only round when going to a lower scale */
			mul = scales[at->scale-tp->scale];
			rnd = mul>>1;

#ifdef HAVE_HGE
			if (a->data.vtype == TYPE_hge) {
				val = a->data.val.hval;
			} else
#endif
			if (a->data.vtype == TYPE_lng) {
				val = a->data.val.lval;
			} else if (a->data.vtype == TYPE_int) {
				val = a->data.val.ival;
			} else if (a->data.vtype == TYPE_sht) {
				val = a->data.val.shval;
			} else if (a->data.vtype == TYPE_bte) {
				val = a->data.val.btval;
			}

			val += rnd;
			val /= mul;

			a->tpe = *tp;
			a->data.vtype = tp->type->localtype;
#ifdef HAVE_HGE
			if (a->data.vtype == TYPE_hge) {
				a->data.val.hval = val;
			} else if (a->data.vtype == TYPE_lng) {
				if ( ((hge) GDK_lng_min > val || val > (hge) GDK_lng_max))
					return 0;
				a->data.val.lval = (lng) val;
			} else if (a->data.vtype == TYPE_int) {
				if ( ((hge) GDK_int_min > val || val > (hge) GDK_int_max))
					return 0;
				a->data.val.ival = (int) val;
			} else if (a->data.vtype == TYPE_sht) {
				if ( ((hge) GDK_sht_min > val || val > (hge) GDK_sht_max))
					return 0;
				a->data.val.shval = (sht) val;
			} else if (a->data.vtype == TYPE_bte) {
				if ( ((hge) GDK_bte_min > val || val > (hge) GDK_bte_max))
					return 0;
				a->data.val.btval = (bte) val;
			}
#else
			if (a->data.vtype == TYPE_lng) {
				a->data.val.lval = (lng) val;
			} else if (a->data.vtype == TYPE_int) {
				if ( ((lng) GDK_int_min > val || val > (lng) GDK_int_max))
					return 0;
				a->data.val.ival = (int) val;
			} else if (a->data.vtype == TYPE_sht) {
				if ( ((lng) GDK_sht_min > val || val > (lng) GDK_sht_max))
					return 0;
				a->data.val.shval = (sht) val;
			} else if (a->data.vtype == TYPE_bte) {
				if ( ((lng) GDK_bte_min > val || val > (lng) GDK_bte_max))
					return 0;
				a->data.val.btval = (bte) val;
			}
#endif
			return 1;
		}