Code for the sql server type conversion rules (and implicit/explicit
casting)
The plan is to follow the same functions as postgresql support for now:
findCallMatch
resolveResultSetType
checkAssignmentValid
The rules in sql server for implicit casting and function resolution
are quite different to postgresql. The biggest one is that e.g. select
cast(1 as int) + cast('2' as varchar(20)) works in sql server but not
in postgresql.
just hack for operators for now: if one argument is a number type, and
the other is a text type, then cast the text to number.
> {-# LANGUAGE PatternGuards,OverloadedStrings #-}
> module Database.HsSqlPpp.Internals.TypeChecking.TypeConversion.SqlTypeConversion (
> findCallMatch
> ) where
>
>
>
>
>
>
>
>
> import Database.HsSqlPpp.Internals.TypesInternal
> import Database.HsSqlPpp.Internals.Dialect
> import Database.HsSqlPpp.Internals.Catalog.CatalogInternal
> import Database.HsSqlPpp.Internals.Catalog.CatalogTypes
>
>
> import qualified Database.HsSqlPpp.Internals.TypeChecking.TypeConversion.OldTypeConversion as T
> import Data.Text (Text)
> findCallMatch :: Dialect -> Catalog -> Text -> [Type] -> Either [TypeError] OperatorPrototype
> findCallMatch d cat fnName argsType =
> case argsType of
> [_a,_b] | Just x <- checkOperator d cat fnName argsType -> Right x
> _ -> T.findCallMatch d cat fnName argsType
hack to allow implicit casting one of the args to a numeric operator
from a text type to the correct numeric type:
check is an operator
check on arg is numeric, the other text
match an exact operator itself with two args the same numeric type
- in this case, cast the text arg to the numeric type and return a match
> checkOperator :: Dialect -> Catalog -> Text -> [Type] -> Maybe OperatorPrototype
> checkOperator d cat fnName [a,b] | Just t <- ty a b =
>
>
> let nm = catLookupFns cat fnName
>
>
> cands = filter (\(_,as,_,_) -> as == [t,t]) nm
> in case cands of
> [c] -> return c
> _ -> Nothing
> where
> ty a' b' | isNumber a' && isText b' = Just a'
> ty a' b' | isText a' && isNumber b' = Just b'
> ty _ _ = Nothing
> isNumber x =
> x `elem` (map ScalarType $ diNumberTypes d)
>
> isText x =
> x `elem` (map ScalarType $ diTextTypes d)
>
> checkOperator _ _ _ _ = Nothing