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; }
/* 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; }