hmssql
Safe HaskellNone
LanguageHaskell2010

Hmssql.Types

Description

The Haskell types that stand for SQL Server's, and which SQL types each decodes from and is sent as. The value types of hmssql's own (Money, DateTimeOffset, RawValue, RawParam; Hmssql.SqlValue for a value of any type) are defined or re-exported here; the rest are the usual base, text, bytestring, time, Decimal and uuid-types types.

Decoding: FromSqlField

A column's SQL type is checked against the Haskell type when the result set's columns arrive, before any row is decoded. Maybe a decodes NULL as Nothing for any a below; a NULL in a column decoded as a bare type is a DecodeError.

Haskell typeSQL types accepted
Boolbit
Int, Int8, Int16, Int32, Int64, Word8tinyint, smallint, int, bigint, bit; a value outside the Haskell type's range is an error
Integerthe integer types, and decimal or numeric with scale 0
Doublefloat, real
Floatreal (float(24)); float(53) is refused rather than rounded
Decimaldecimal, numeric, money, smallmoney, the integer types
Moneymoney, smallmoney
UUIDuniqueidentifier
Text, String, lazy Textnchar, nvarchar, ntext, xml, and char, varchar, text in UTF-8 or a supported single-byte code page
ByteString, lazy ByteStringbinary, varbinary, image, and the undecoded bytes of char, varchar, text
LocalTimedatetime, smalldatetime, datetime2, date (at midnight)
UTCTimethe same, taken to be UTC, and datetimeoffset, converted to UTC
DateTimeOffset, ZonedTimedatetimeoffset
Daydate
TimeOfDaytime
SqlValue any type but a CLR user-defined type; a sql_variant as its base type
RawValueany type, as the bytes on the wire

rowversion is binary(8) on the wire, json is nvarchar(max) and vector is varchar: each decodes as what it is sent as. A CLR user-defined type (hierarchyid, geometry, geography) decodes only as RawValue; CAST it or call .ToString() in the query instead.

Encoding: ToSqlField

A parameter's wire type is fixed by its Haskell type. The server converts it to the column's type where it can, but sending nvarchar against a varchar index, or datetime2 against a datetime column, can turn a seek into a scan; RawParam chooses the wire type yourself. Nothing is a NULL of the type the bare type would be sent as.

Haskell typeSent as
Boolbit
Word8tinyint
Int8, Int16smallint
Int32int
Int, Int64bigint
Integer bigint, or decimal(38,0) beyond its range; 39 digits or more is an EncodeError
Doublefloat
Floatreal
Decimaldecimal(p,s) with the value's own scale and just enough precision
Moneymoney
UUIDuniqueidentifier
Text, String, lazy Textnvarchar(4000), or nvarchar(max) beyond 4000 UTF-16 code units
ByteString, lazy ByteStringvarbinary(8000), or varbinary(max) beyond 8000 bytes
LocalTimedatetime2(7)
UTCTimedatetime2(7) holding the UTC clock time
DateTimeOffset, ZonedTimedatetimeoffset(7); the offset must be within ±14:00
Daydate
TimeOfDaytime(7)
SqlValue the type its constructor names; SqlNull as an nvarchar(max) NULL
RawParamthe TypeInfo given, with the bytes given

Date and time values are rounded to 100 ns as the server rounds them; a value the server would reject (a year outside 1 through 9999, an offset beyond ±14:00) is an EncodeError before anything is sent. A NULL of Text, SqlParam or RawParam is nvarchar(max), which the server converts to most types but not to binary or sql_variant: send a typed NULL (Nothing :: Maybe Int32) there.

When a string's declared type matters

A string or binary parameter's declared type depends on the value's length, as the table shows, and on whether it is NULL. The declared type doesn't limit what can be sent, and it doesn't change the result of storing the value in a column or comparing it with one. It does matter in three cases:

  • An expression typed by the parameter. SELECT @p1 returns the declared type, and concatenating bounded types stops at their limit without an error. With two values of 3000 characters, @p1 + @p2 returns 4000 characters and CAST(@p1 AS nvarchar(max)) + @p2 returns 6000. Binary values stop at 8000 bytes in the same way. Cast a parameter whose result can outgrow the limit.
  • A sql_variant target. The server won't convert a (max) type to sql_variant, so a longer value or an untyped NULL fails with error 206.
  • Plan caching. The server caches a plan per declaration, so one statement can have one plan for short values and another for long values and NULLs. Values within one declaration share a plan whatever their lengths.
Synopsis

hmssql's own value types

newtype Money Source #

A money or smallmoney value: a fixed-point number with four decimal places, exactly as the server stores it.

Constructors

Money (Fixed E4) 

Instances

Instances details
Num Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Fractional Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Real Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Methods

toRational :: Money -> Rational #

RealFrac Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Methods

properFraction :: Integral b => Money -> (b, Money) #

truncate :: Integral b => Money -> b #

round :: Integral b => Money -> b #

ceiling :: Integral b => Money -> b #

floor :: Integral b => Money -> b #

Show Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Methods

showsPrec :: Int -> Money -> ShowS #

show :: Money -> String #

showList :: [Money] -> ShowS #

Eq Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Methods

(==) :: Money -> Money -> Bool #

(/=) :: Money -> Money -> Bool #

Ord Money Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Methods

compare :: Money -> Money -> Ordering #

(<) :: Money -> Money -> Bool #

(<=) :: Money -> Money -> Bool #

(>) :: Money -> Money -> Bool #

(>=) :: Money -> Money -> Bool #

max :: Money -> Money -> Money #

min :: Money -> Money -> Money #

FromSqlField Money Source #

money and smallmoney, with all four decimal places.

Instance details

Defined in Hmssql.Decoding

ToSqlField Money Source #

money; values outside its range (±922,337,203,685,477.58) are rejected.

Instance details

Defined in Hmssql.Encoding

Methods

fieldEncoder :: FieldEncoder Money Source #

fieldParam :: Money -> FieldParams -> FieldParams

data DateTimeOffset Source #

A datetimeoffset value: an instant plus the UTC offset it was recorded with.

Constructors

DateTimeOffset 

Fields

Instances

Instances details
Show DateTimeOffset Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Eq DateTimeOffset Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Ord DateTimeOffset Source # 
Instance details

Defined in Hmssql.Tds.Primitives

FromSqlField DateTimeOffset Source # 
Instance details

Defined in Hmssql.Decoding

ToSqlField DateTimeOffset Source #

datetimeoffset(7), rounded like LocalTime. The offset must be within ±14:00 and both the UTC and the local time within years 1 through 9999.

Instance details

Defined in Hmssql.Encoding

Methods

fieldEncoder :: FieldEncoder DateTimeOffset Source #

fieldParam :: DateTimeOffset -> FieldParams -> FieldParams

dateTimeOffsetToZonedTime :: DateTimeOffset -> ZonedTime Source #

The same instant as a ZonedTime in the value's offset.

zonedTimeToDateTimeOffset :: ZonedTime -> DateTimeOffset Source #

An offset beyond the range of Int16 is clamped to it rather than wrapped (so it stays outside the ±14:00 a datetimeoffset allows, and putDateTimeOffset rejects it).

The bytes as they are

newtype RawValue Source #

The bytes of any column's value as the server sends them, including the CLR types hmssql doesn't otherwise decode.

Constructors

RawValue ByteString 

newtype RawParam Source #

Send a value with an explicit wire type.

Constructors

RawParam (TypeInfo, RawBytes) 

Instances

Instances details
ToSqlField RawParam Source # 
Instance details

Defined in Hmssql.Encoding

Methods

fieldEncoder :: FieldEncoder RawParam Source #

fieldParam :: RawParam -> FieldParams -> FieldParams

The wire's view of a type

data TypeInfo Source #

A type as the wire describes it (MS-TDS 2.2.5.4 TYPE_INFO): the token's type byte with its length, precision and scale, or collation, as the server sends it in COLMETADATA and a client sends it for a parameter. The wire has fewer types than T-SQL (int arrives as TIIntN 4 or TIInt4; json and vector as character types): Hmssql.SqlType names the declared type. RawParam takes one to send a value with a wire type of your choosing.

Constructors

TINull

0x1F

TIBit

0x32

TIInt1

0x30

TIInt2

0x34

TIInt4

0x38

TIInt8

0x7F

TIMoney4

0x7A

TIMoney8

0x3C

TIDateTime4

0x3A

TIDateTime8

0x3D

TIFlt4

0x3B

TIFlt8

0x3E

TIBitN

0x68

TIIntN !Word8

0x26, length 124/8

TIMoneyN !Word8

0x6E, length 4/8

TIDateTimeN !Word8

0x6F, length 4/8

TIFltN !Word8

0x6D, length 4/8

TIGuid

0x24

TIDecimalN !Precision !Scale

0x6A

TINumericN !Precision !Scale

0x6C

TIDateN

0x28

TITimeN !Scale

0x29

TIDateTime2N !Scale

0x2A

TIDateTimeOffsetN !Scale

0x2B

TIBigChar !Word16 !Collation

0xAF

TIBigVarChar !Word16 !Collation

0xA7, 0xFFFF = max

TIText !Word32 !Collation

0x23

TINChar !Word16 !Collation

0xEF

TINVarChar !Word16 !Collation

0xE7, 0xFFFF = max

TINText !Word32 !Collation

0x63

TIBigBinary !Word16

0xAD

TIBigVarBinary !Word16

0xA5, 0xFFFF = max

TIImage !Word32

0x22

TIXml !(Maybe XmlSchema)

0xF1

TISqlVariant !Word32

0x62

TIUdt !UdtInfo

0xF0, a CLR user-defined type (hierarchyid, geometry, geography, ...). Parsed so a result containing one can be read past, but not decoded (Hmssql.Decoding rejects it except as raw bytes) nor sent (typeInfoProblem).

Instances

Instances details
Show TypeInfo Source # 
Instance details

Defined in Hmssql.Tds.TypeInfo

Eq TypeInfo Source # 
Instance details

Defined in Hmssql.Tds.TypeInfo

data Collation Source #

MS-TDS 2.2.5.1.2 Collation Rule Definition. Kept opaque: the LCID, flags and version share a DWORD, followed by the sort ID byte.

Constructors

Collation 

Instances

Instances details
Show Collation Source # 
Instance details

Defined in Hmssql.Tds.Primitives

Eq Collation Source # 
Instance details

Defined in Hmssql.Tds.Primitives

data ColumnInfo Source #

A column of a result set, as its COLMETADATA describes it.

Constructors

ColumnInfo 

Fields

Instances

Instances details
Show ColumnInfo Source # 
Instance details

Defined in Hmssql.Tds.Token

Eq ColumnInfo Source # 
Instance details

Defined in Hmssql.Tds.Token

columnIsNullable :: ColumnInfo -> Bool Source #

Whether the column may hold NULL.

columnIsLong :: ColumnInfo -> Bool Source #

Whether a column's values may be of any length: a max type, xml, json, a CLR type, or a legacy text, ntext or image, which arrive in pieces rather than behind a length of at most 8,000 bytes. Such a column is the one to read with a FoldingCell or streamField.

data ServerMessage Source #

A message from the server: an error (SqlServerError) or an informational message (PRINT output, a low-severity message; connectOnInfoMessage).

Constructors

ServerMessage 

Fields

Instances

Instances details
Show ServerMessage Source # 
Instance details

Defined in Hmssql.Tds.Token

Eq ServerMessage Source # 
Instance details

Defined in Hmssql.Tds.Token