Обсуждение: Re: [HACKERS] Automatic type conversion
> >Postgres has type extensibility, so the algorithms for matching up types >and functions need to be very general. In this case, there is only one >function defined for factorial, and it takes an integer argument. But of >course Postgres now says "ah! I know how to make an int from a float!" >and goes ahead and does it. If there were more than one function defined >for factorial, and if none of the arguments matched a float, then >Postgres would conclude that there are too many functions to choose from >and throw an error. Making an int from a float is only defined for "small" values of the float. So for the general case such a conversion would simply overflow the int, giving it an undefined value. Does this make sense to you? > >One way to address this is to never allow Postgres to "demote" a type; >i.e. Postgres would be allowed to promote arguments to a "higher" type >(e.g. int->float) but never allowed to demote arguments (e.g. >float->int). But this would severely restrict type matching. I wanted to >try the more flexible case first to see whether it really does the >"wrong thing"; in the case of factorial, the only recourse for someone >wanting to calculate a factorial from a float is to convert to an int >first anyway. Please bear with me since I haven't looked at the code. Are conversions between types defined in a way that is also extensible? I'm trying to say that if I add a new type to the system, can I also specify which conversions are automatically allowed? (Something similar to the C++ "explicite" keyword?). > >Or, again for this factorial case, we can implement a floating point >factorial with either the gamma function (whatever that is :) or with an >explicit routine which checks for non-integral values. And properly handles overflows. > >Could also print a notice when arguments are being converted, but that >might get annoying for most cases which are probably trivial ones. > > - Tom Regards, Maurice.
> Making an int from a float is only defined for "small" values of the > float. So for the general case such a conversion would simply overflow > the int, giving it an undefined value. Does this make sense to you? Yes, it does. Look, I'm not saying everyone _should_ call factorial with a float, only that if someone does, Postgres will try to accomplish it. Doesn't it make sense to you? > Are conversions between types defined in a way that is also > extensible? I'm trying to say that if I add a new type to the system, > can I also specify which conversions are automatically allowed? > (Something similar to the C++ "explicite" keyword?). Yes, they are extensible in the sense that all conversions (except for a few string type hacks at the moment) are done by looking for a function named with the same name as the target type, taking as a single argument one with the specified source type. If you define one, then Postgres can use it for conversions. At the moment the primary mechanism uses the pg_proc table to look for possible conversion functions, along with a hardcoded notion of what "preferred types" and "type categories" are for the builtin types. For user-defined types, explicit type conversion functions must be provided _and_ there must be a single path from source to possible targets for the conversions. Otherwise there will result multiple possible conversions and Postgres will ask you to use a cast, much as it does in v6.3.x and before. > >Or, again for this factorial case, we can implement a floating point > >factorial with either the gamma function (whatever that is :) or with > >an explicit routine which checks for non-integral values. > And properly handles overflows. Hey, it doesn't do any worse than before... - Tom