Skip to content

Commit 713fa49

Browse files
authored
Fixed DataSync not generating the correct sql query for null conditions (#1359)
E.g. a condition like `where('field', null')` needs to add a SQL condition like `WHERE field IS NULL` instead of `WHERE field = NULL`
2 parents 9a42824 + e3f4505 commit 713fa49

File tree

3 files changed

+45
-2
lines changed

3 files changed

+45
-2
lines changed

IHP/DataSync/DynamicQuery.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ data ConditionOperator
6363
| OpNotEqual -- ^ a <> b
6464
| OpAnd -- ^ a AND b
6565
| OpOr -- ^ a OR b
66+
| OpIs -- ^ a IS b
67+
| OpIsNot -- ^ a IS NOT b
6668
deriving (Show, Eq)
6769

6870
data SelectedColumns

IHP/DataSync/DynamicQueryCompiler.hs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,19 @@ compileSelectedColumns (SelectSpecific fields) = PG.Many args
7070
compileCondition :: ConditionExpression -> (PG.Query, [PG.Action])
7171
compileCondition (ColumnExpression column) = ("?", [PG.toField $ PG.Identifier (fieldNameToColumnName column)])
7272
compileCondition NullExpression = ("NULL", [])
73-
compileCondition (InfixOperatorExpression a operator b) = ("(" <> queryA <> ") " <> compileOperator operator <> " (" <> queryB <> ")", paramsA <> paramsB)
73+
compileCondition (InfixOperatorExpression a OpEqual NullExpression) = compileCondition (InfixOperatorExpression a OpIs NullExpression) -- Turn 'a = NULL' into 'a IS NULL'
74+
compileCondition (InfixOperatorExpression a OpNotEqual NullExpression) = compileCondition (InfixOperatorExpression a OpIsNot NullExpression) -- Turn 'a <> NULL' into 'a IS NOT NULL'
75+
compileCondition (InfixOperatorExpression a operator b) = ("(" <> queryA <> ") " <> compileOperator operator <> " " <> rightOperand, paramsA <> paramsB)
7476
where
7577
(queryA, paramsA) = compileCondition a
7678
(queryB, paramsB) = compileCondition b
79+
80+
rightOperand = if rightParentheses
81+
then "(" <> queryB <> ")"
82+
else queryB
83+
84+
rightParentheses :: Bool
85+
rightParentheses = b /= NullExpression
7786
compileCondition (LiteralExpression literal) = ("?", [toValue literal])
7887
where
7988
toValue (IntValue int) = PG.toField int
@@ -93,4 +102,6 @@ compileOperator OpGreaterThanOrEqual = ">="
93102
compileOperator OpLessThanOrEqual = "<="
94103
compileOperator OpNotEqual = "<>"
95104
compileOperator OpAnd = "AND"
96-
compileOperator OpOr = "OR"
105+
compileOperator OpOr = "OR"
106+
compileOperator OpIs = "IS"
107+
compileOperator OpIsNot = "IS NOT"

Test/DataSync/DynamicQueryCompiler.hs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,34 @@ tests = do
134134
compileQuery query `shouldBe`
135135
( "SELECT ? FROM ? WHERE (?) = (?) LIMIT ? OFFSET ?"
136136
, [PG.Plain "*", PG.EscapeIdentifier "posts", PG.EscapeIdentifier "user_id", PG.Escape "b8553ce9-6a42-4a68-b5fc-259be3e2acdc", PG.Plain "25", PG.Plain "50"]
137+
)
138+
139+
it "compile 'field = NULL' conditions to 'field IS NULL'" do
140+
let query = DynamicSQLQuery
141+
{ table = "posts"
142+
, selectedColumns = SelectAll
143+
, whereCondition = Just $ InfixOperatorExpression (ColumnExpression "userId") OpEqual NullExpression
144+
, orderByClause = []
145+
, limit = Nothing
146+
, offset = Nothing
147+
}
148+
149+
compileQuery query `shouldBe`
150+
( "SELECT ? FROM ? WHERE (?) IS NULL"
151+
, [PG.Plain "*", PG.EscapeIdentifier "posts", PG.EscapeIdentifier "user_id"]
152+
)
153+
154+
it "compile 'field <> NULL' conditions to 'field IS NOT NULL'" do
155+
let query = DynamicSQLQuery
156+
{ table = "posts"
157+
, selectedColumns = SelectAll
158+
, whereCondition = Just $ InfixOperatorExpression (ColumnExpression "userId") OpNotEqual NullExpression
159+
, orderByClause = []
160+
, limit = Nothing
161+
, offset = Nothing
162+
}
163+
164+
compileQuery query `shouldBe`
165+
( "SELECT ? FROM ? WHERE (?) IS NOT NULL"
166+
, [PG.Plain "*", PG.EscapeIdentifier "posts", PG.EscapeIdentifier "user_id"]
137167
)

0 commit comments

Comments
 (0)