13

Persistent を使用して、SQL バックエンドで Haskell の合計型を表現するための賢明な方法を見つけようとしています。

私のターゲットHaskellデータ型は、

data Widget = FooWidget Int | BarWidget T.Text

data HElement = HElement 
   { name   :: T.Text
   , widget :: Widget
   }

次の永続データ型を使用してこれらをモデル化しています。

Element
  name    T.Text

Foo
  elementId ElementId
  size      Int

Bar
  elementId ElementId
  colour    T.Text

各要素には Foo または Bar のいずれかのみが存在し、両方は存在しません。

Left Outer Joina を使用して、すべての要素と対応する Foo OR Bar を選択したいと考えています。私の Esqueleto 式は次のとおりです。

select $ 
from $ \(elem `LeftOuterJoin` foo `LeftOuterJoin` bar) -> do
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
on (just (elem ^. ElementId) ==. bar ?. BarElementId)
return (elem, foo, bar)

ただし、コードを実行すると、次のエラーが発生します。

user error (Postgresql.withStmt': bad result status FatalError (("PGRES_FATAL_ERROR","ERROR:  missing FROM-clause entry for table

2 番目の結合を削除すると、次のようになります。

select $ 
from $ \(elem `LeftOuterJoin` foo) -> do
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
return (elem, foo)

コードはエラーなしで実行されます。明らかだと思いますが、何が間違っているのかわかりません。


編集:問題が何であるかがわかりました。ドキュメントから:

ON 句の順序が逆になっていることに注意してください。構成可能性に役立つため、 ons を逆の順序で記述する必要があります (詳細については on のドキュメントを参照してください)。

次のコードが機能します (on式の順序が逆になっています)。

select $
from $ \(elem `LeftOuterJoin` foo `LeftOuterJoin` bar) -> do
on (just (elem ^. ElementId) ==. bar ?. BarElementId)
on (just (elem ^. ElementId) ==. foo ?. FooElementId)
return (elem,foo,bar)

ありがとう、

マイケル

4

1 に答える 1