Skip to content

Commit

Permalink
Fixed 'DEFAULT is not allowed in this context' problem with createRec…
Browse files Browse the repository at this point in the history
…ord when using array columns
  • Loading branch information
mpscholten committed Jul 29, 2024
1 parent 9da30cd commit 0cc8531
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 3 deletions.
25 changes: 25 additions & 0 deletions Test/SchemaCompilerSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,31 @@ tests = do
builder |> QueryBuilder.filterWhere (#id, id)
{-# INLINE filterWhereId #-}
|]
it "should not use DEFAULT for array columns" do
let statement = StatementCreateTable CreateTable
{ name = "users"
, columns =
[ Column "id" PUUID Nothing True True Nothing
, Column {name = "keywords", columnType = PArray PText, defaultValue = Just (VarExpression "NULL"), notNull = False, isUnique = False, generator = Nothing}
]
, primaryKeyConstraint = PrimaryKeyConstraint ["id"]
, constraints = []
, unlogged = False
}
let compileOutput = compileStatementPreview [statement] statement |> Text.strip

getInstanceDecl "CanCreate" compileOutput `shouldBe` [trimming|
instance CanCreate User where
create :: (?modelContext :: ModelContext) => User -> IO User
create model = do
sqlQuerySingleRow "INSERT INTO users (id, keywords) VALUES (?, ? :: TEXT[]) RETURNING id, keywords" ((model.id, model.keywords))
createMany [] = pure []
createMany models = do
sqlQuery (Query $ "INSERT INTO users (id, keywords) VALUES " <> (ByteString.intercalate ", " (List.map (\_ -> "(?, ? :: TEXT[])") models)) <> " RETURNING id, keywords") (List.concat $ List.map (\model -> [toField (model.id), toField (model.keywords)]) models)
createRecordDiscardResult :: (?modelContext :: ModelContext) => User -> IO ()
createRecordDiscardResult model = do
sqlExecDiscardResult "INSERT INTO users (id, keywords) VALUES (?, ? :: TEXT[])" ((model.id, model.keywords))
|]
describe "compileStatementPreview for table with arbitrarily named primary key" do
let statements = parseSqlStatements [trimming|
CREATE TABLE things (
Expand Down
15 changes: 12 additions & 3 deletions ihp-ide/IHP/SchemaCompiler.hs
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,18 @@ compileCreate table@(CreateTable { name, columns }) =
values = commaSep (map columnPlaceholder writableColumns)

toBinding column@(Column { name }) =
if hasExplicitOrImplicitDefault column
then "fieldWithDefault #" <> columnNameToFieldName name <> " model"
else "model." <> columnNameToFieldName name
if hasExplicitOrImplicitDefault column && not isArrayColumn
then "fieldWithDefault #" <> columnNameToFieldName name <> " model"
else "model." <> columnNameToFieldName name
where
-- We cannot use DEFAULT with array columns as postgres will throw an error:
--
-- > DEFAULT is not allowed in this context
--
-- To walk around this error, we explicitly specify an empty array.
isArrayColumn = case column.columnType of
PArray _ -> True
_ -> False


bindings :: [Text]
Expand Down

0 comments on commit 0cc8531

Please sign in to comment.