mssql: basic support for geography and geometry types

GitOrigin-RevId: 97bbf0e8d53b00c9f4365b145adb19bdcd769ceb
This commit is contained in:
Vamshi Surabhi 2021-02-24 18:22:21 +05:30 committed by hasura-bot
parent 6fb181a4ee
commit 74a58fb66c
5 changed files with 36 additions and 12 deletions

View File

@ -1,6 +1,12 @@
# Hasura GraphQL Engine Changelog # Hasura GraphQL Engine Changelog
## Next release ## Next release
### Bug fixes and improvements
- server/mssql: fix runtime errors when selecting geography/geometry columns
## v1.4.0-alpha.2
### MSSQL support ### MSSQL support
It's now possible to add a MSSQL server as a source. For now, only read-only queries and subscriptions are supported. It's now possible to add a MSSQL server as a source. For now, only read-only queries and subscriptions are supported.

View File

@ -587,14 +587,20 @@ fromAnnColumnField ::
-> ReaderT EntityAlias FromIr Expression -> ReaderT EntityAlias FromIr Expression
fromAnnColumnField _stringifyNumbers annColumnField = do fromAnnColumnField _stringifyNumbers annColumnField = do
fieldName <- fromPGCol pgCol fieldName <- fromPGCol pgCol
if asText || True -- TODO: FIXME: -- TODO: Handle stringifying large numbers
-- TODO: Does MSSQL support bignums? Probably, but needs researching. {-(IR.isScalarColumnWhere PG.isBigNum typ && stringifyNumbers == StringifyNumbers)-}
{-(IR.isScalarColumnWhere PG.isBigNum typ && stringifyNumbers == StringifyNumbers)-}
then pure (ToStringExpression (ColumnExpression fieldName)) -- for geometry and geography values, the automatic json encoding on sql
-- server would fail. So we need to convert it to a format the json encoding
-- handles. Ideally we want this representation to be GeoJSON but sql server
-- doesn't have any functions to convert to GeoJSON format. So we return it in
-- WKT format
if typ == (IR.ColumnScalar GeometryType) || typ == (IR.ColumnScalar GeographyType)
then pure $ MethodExpression (ColumnExpression fieldName) "STAsText" []
else pure (ColumnExpression fieldName) else pure (ColumnExpression fieldName)
where where
IR.AnnColumnField { _acfInfo = IR.ColumnInfo{pgiColumn=pgCol,pgiType=_typ} IR.AnnColumnField { _acfInfo = IR.ColumnInfo{pgiColumn=pgCol,pgiType=typ}
, _acfAsText = asText :: Bool , _acfAsText = _asText :: Bool
, _acfOp = _ :: Maybe (IR.ColumnOp 'MSSQL) -- TODO: What's this? , _acfOp = _ :: Maybe (IR.ColumnOp 'MSSQL) -- TODO: What's this?
} = annColumnField } = annColumnField

View File

@ -3,8 +3,7 @@
-- | -- |
module Hasura.Backends.MSSQL.Meta module Hasura.Backends.MSSQL.Meta
( MetadataError(..) ( loadDBMetadata
, loadDBMetadata
) where ) where
import Hasura.Prelude import Hasura.Prelude
@ -31,10 +30,6 @@ import Hasura.SQL.Backend
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Loader -- Loader
data MetadataError
= UnknownScalarType Text
deriving (Show)
loadDBMetadata :: Connection -> IO (DBTablesMetadata 'MSSQL) loadDBMetadata :: Connection -> IO (DBTablesMetadata 'MSSQL)
loadDBMetadata conn = do loadDBMetadata conn = do
let sql = $(Q.sqlFromFile "src-rsr/mssql_table_metadata.sql") let sql = $(Q.sqlFromFile "src-rsr/mssql_table_metadata.sql")
@ -179,6 +174,8 @@ parseScalarType = \case
"varbinary" -> VarbinaryType "varbinary" -> VarbinaryType
"bit" -> BitType "bit" -> BitType
"uniqueidentifier" -> GuidType "uniqueidentifier" -> GuidType
"geography" -> GeographyType
"geometry" -> GeometryType
t -> UnknownType t t -> UnknownType t

View File

@ -93,6 +93,10 @@ fromExpression =
"(" <+> fromExpression x <+> ") != (" <+> fromExpression y <+> ")" "(" <+> fromExpression x <+> ") != (" <+> fromExpression y <+> ")"
ToStringExpression e -> "CONCAT(" <+> fromExpression e <+> ", '')" ToStringExpression e -> "CONCAT(" <+> fromExpression e <+> ", '')"
SelectExpression s -> "(" <+> IndentPrinter 1 (fromSelect s) <+> ")" SelectExpression s -> "(" <+> IndentPrinter 1 (fromSelect s) <+> ")"
MethodExpression field method args ->
fromExpression field <+> "." <+>
fromString (T.unpack method) <+>
"(" <+> (SeqPrinter $ map fromExpression args) <+> ")"
OpExpression op x y -> OpExpression op x y ->
"(" <+> "(" <+>
fromExpression x <+> fromExpression x <+>

View File

@ -157,6 +157,8 @@ data Expression
-- behave like it knows your field is JSON and not double-encode -- behave like it knows your field is JSON and not double-encode
-- it. -- it.
| ToStringExpression Expression | ToStringExpression Expression
-- expression.text(e1, e2, ..)
| MethodExpression !Expression !Text ![Expression]
| JsonValueExpression Expression JsonPath | JsonValueExpression Expression JsonPath
-- ^ This is for getting actual atomic values out of a JSON -- ^ This is for getting actual atomic values out of a JSON
-- string. -- string.
@ -266,6 +268,8 @@ data ScalarType
| TinyintType | TinyintType
| BitType | BitType
| GuidType | GuidType
| GeographyType
| GeometryType
| UnknownType !Text | UnknownType !Text
scalarTypeDBName :: ScalarType -> Text scalarTypeDBName :: ScalarType -> Text
@ -291,6 +295,8 @@ scalarTypeDBName = \case
TinyintType -> "tinyint" TinyintType -> "tinyint"
BitType -> "bit" BitType -> "bit"
GuidType -> "uniqueidentifier" GuidType -> "uniqueidentifier"
GeographyType -> "geography"
GeometryType -> "geometry"
-- the input form for types that aren't explicitly supported is a string -- the input form for types that aren't explicitly supported is a string
UnknownType t -> t UnknownType t -> t
@ -317,6 +323,11 @@ parseScalarValue scalarType jValue = case scalarType of
TinyintType -> ODBC.IntValue <$> parseJValue jValue TinyintType -> ODBC.IntValue <$> parseJValue jValue
BitType -> ODBC.ByteValue <$> parseJValue jValue BitType -> ODBC.ByteValue <$> parseJValue jValue
GuidType -> ODBC.TextValue <$> parseJValue jValue GuidType -> ODBC.TextValue <$> parseJValue jValue
-- TODO: We'll need to wrap this with geography::STGeomFromText
GeographyType -> ODBC.TextValue <$> parseJValue jValue
GeometryType -> ODBC.TextValue <$> parseJValue jValue
-- the input format for types that aren't explicitly supported is a string -- the input format for types that aren't explicitly supported is a string
UnknownType _ -> ODBC.TextValue <$> parseJValue jValue UnknownType _ -> ODBC.TextValue <$> parseJValue jValue
where where