Skip to content

Question marks in string literals cause substitution errors#54

Merged
paul-rouse merged 8 commits intopaul-rouse:masterfrom
parsonsmatt:matt/question-marks
Mar 19, 2022
Merged

Question marks in string literals cause substitution errors#54
paul-rouse merged 8 commits intopaul-rouse:masterfrom
parsonsmatt:matt/question-marks

Conversation

@parsonsmatt
Copy link
Copy Markdown
Contributor

Currently just a failing test but I hope to have a fix up soon

Cf yesodweb/persistent#1375

-- break a fragment if the question mark is in a string literal.
splitQuery :: ByteString -> [Builder]
splitQuery s =
reverse $ fmap (fromByteString . BS.pack . reverse) $
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: dlist this

test/main.hs Outdated
Comment on lines +30 to +31
describe "Database.MySQL.Simple.unitSpec" unitSpec
describe "Database.MySQL.Simple.integrationSpec" $ integrationSpec conn
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changed up the hspec formatting a bit

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I've just introduced a conflict here - maybe rebase, if you would.

'\'' ->
normal ret (c : acc) cs
_ ->
quotes ret (c : acc) cs
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about breaking out attoparsec for this. Not sure what any potential performance improvements would be.

I'll likely need to factor this out into a library, anyway, since Postgres also needs it. Then that lib can be tested/benchmarked and work well.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

attoparsec is already a dependency, so absolutely fine if you want to use it!

Comment on lines +52 to +64
describe "splitQuery" $ do
it "works for a single question mark" $ do
splitQuery "select * from foo where name = ?"
`shouldBe`
["select * from foo where name = ", ""]
it "works with a question mark in a string literal" $ do
splitQuery "select 'hello?'"
`shouldBe`
["select 'hello?'"]
it "works with many question marks" $ do
splitQuery "select ? + ? + what from foo where bar = ?"
`shouldBe`
["select ", " + ", " + what from foo where bar = ", ""]
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests ensure that it behaves appropriately when formatting for other functions

Comment on lines +78 to +99
it "can have question marks in string literals" $ do
result <- query_ conn "select 'hello?'"
result `shouldBe` [Only ("hello?" :: Text)]
describe "query" $ do
it "can have question marks in string literals" $ do
result <- query conn "select 'hello?'" ()
result `shouldBe` [Only ("hello?" :: Text)]
describe "with too many query params" $ do
it "should have the right message" $ do
(query conn "select 'hello?'" (Only ['a']) :: IO [Only Text])
`shouldThrow`
(\e -> fmtMessage e == "0 '?' characters, but 1 parameters")
describe "with too few query params" $ do
it "should have the right message" $ do
(query conn "select 'hello?' = ?" () :: IO [Only Text])
`shouldThrow`
(\e -> fmtMessage e == "1 '?' characters, but 0 parameters")
describe "formatQuery" $ do
it "should not blow up on a question mark in string literal" $ do
formatQuery conn "select 'hello?'" ()
`shouldReturn`
"select 'hello?'"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and then these ensure it works in query etc

Comment on lines +85 to +94
describe "with too many query params" $ do
it "should have the right message" $ do
(query conn "select 'hello?'" (Only ['a']) :: IO [Only Text])
`shouldThrow`
(\e -> fmtMessage e == "0 '?' characters, but 1 parameters")
describe "with too few query params" $ do
it "should have the right message" $ do
(query conn "select 'hello?' = ?" () :: IO [Only Text])
`shouldThrow`
(\e -> fmtMessage e == "1 '?' characters, but 0 parameters")
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

love too hspec's shouldThrow

@paul-rouse
Copy link
Copy Markdown
Owner

Thanks for spotting and fixing this!

There's a minor conflict now, so would you mind rebasing - it would be slightly cleaner. I belatedly got round to Github workflow CI, and needed to make a small change in test/main.hs

If you want to use attoparsec, either now or at a future date, that's fine - let me know if you want me to hold on at the moment.

@paul-rouse
Copy link
Copy Markdown
Owner

Great - thanks!

@paul-rouse paul-rouse merged commit 1c8b693 into paul-rouse:master Mar 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants