1``INSERT``, ``UPDATE`` and ``DELETE``
2=====================================
4While the majority of Rel8 is about building and executing ``SELECT``
5statement, Rel8 also has support for ``INSERT``, ``UPDATE`` and ``DELETE``.
6These statements are all executed using the ``insert``, ``update`` and
7``delete`` functions, all of which take a record of parameters.
11 This part of Rel8's API uses the ``DuplicateRecordFields`` language
12 extension. In code that needs to use this API, you should also enable this
13 language extension, or you may get errors about ambiguous field names.
18To perform a ``DELETE`` statement, construct a ``Delete`` value and execute it
19using ``delete``. ``Delete`` takes:
22 The ``TableSchema`` for the table to delete rows from.
25 This is a simple ``Query`` that forms the ``USING`` clause of the ``DELETE``
26 statement. This can be used to join against other tables, and the results
27 can be referenced in the ``deleteWhere`` parameter. For simple ``DELETE``\s
28 where you don't need to do this, you can set ``using = pure ()``.
31 The ``WHERE`` clause of the ``DELETE`` statement. This is a function that
32 takes two inputs: the result of the ``using`` query, and the current value
36 What to return - see :ref:`returning`.
41To perform a ``UPDATE`` statement, construct a ``Update`` value and execute it
42using ``update``. ``Update`` takes:
45 The ``TableSchema`` for the table to update rows in.
48 This is a simple ``Query`` that forms the ``FROM`` clause of the ``UPDATE``
49 statement. This can be used to join against other tables, and the results
50 can be referenced in the ``set`` and ``updateWhere`` parameters. For simple
51 ``UPDATE``\s where you don't need to do this, you can set ``from = pure ()``.
54 A row to row transformation function, indicating how to update selected rows.
55 This function takes rows of the same shape as ``target`` but in the ``Expr``
56 context. One way to write this function is to use record update syntax::
58 set = \from row -> row { rowName = "new name" }
61 The ``WHERE`` clause of the ``UPDATE`` statement. This is a function that
62 takes two inputs: the result of the ``from`` query, and the current value of
66 What to return - see :ref:`returning`.
71To perform a ``INSERT`` statement, construct a ``Insert`` value and execute it
72using ``insert``. ``Insert`` takes:
75 The ``TableSchema`` for the table to insert rows into.
78 The rows to insert. These are the same as ``into``, but in the ``Expr``
79 context. You can construct rows from their individual fields::
81 rows = values [ MyTable { myTableA = lit "A", myTableB = lit 42 }
83 or you can use ``lit`` on a table value in the ``Result`` context::
85 rows = values [ lit MyTable { myTableA = "A", myTableB = 42 }
88 What should happen if an insert clashes with rows that already exist. This
89 corresponds to PostgreSQL's ``ON CONFLICT`` clause. You can specify:
92 PostgreSQL should abort the ``INSERT`` with an exception
95 PostgreSQL should not insert the duplicate rows.
98 PostgreSQL should instead try to update any existing rows that conflict
99 with rows proposed for insertion.
102 What to return - see :ref:`returning`.
109PostgreSQL has the ability to return extra information after a ``DELETE``,
110``INSERT`` or ``UPDATE`` statement by attaching a ``RETURNING`` clause. A common
111use of this clause is to return any automatically generated sequence values for
112primary key columns. Rel8 supports ``RETURNING`` clauses by filling in the
113``returning`` field and specifying a ``Projection``. A ``Projection`` is a row
114to row transformation, allowing you to project out a subset of fields.
116For example, if we are inserting orders, we might want the order ids returned::
120 , rows = values [ order ]
122 , returning = Projection orderId
125If we don't want to return anything, we can use ``pure ()``::
129 , rows = values [ order ]
131 , returning = pure ()
137It is fairly common to define tables with default values. While Rel8 does not
138have specific functionality for ``DEFAULT``, there are a few options:
141~~~~~~~~~~~~~~~~~~~~~~~~~~~
143Rel8 does not have any special support for ``DEFAULT``. If you need to use
144default column values in inserts, you can use ``unsafeDefault`` to
145construct the ``DEFAULT`` expression::
149 , rows = values [ Order { orderId = unsafeDefault, ... } ]
151 , returning = Projection orderId
155 As the name suggests, this is an unsafe operation. In particular, Rel8 is not
156 able to prove that this column does have a default value, so it may be
157 possible to introduce a runtime error. Furthermore, ``DEFAULT`` is fairly
158 special in SQL, and cannot be combined like other expressions. For example,
159 the innocuous expression::
163 will lead to a runtime crash.
165Reimplement default values in Rel8
166~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
168If you only need to access default values in Rel8, another option is to specify
169them in Rel8, rather than in your database schema.
172 A common default value for primary keys is to use `nextval` to obtain the
173 next value from a sequence. This can be done in Rel8 by using the ``nextval``
178 , rows = values [ Order { orderId = nextval "order_id_seq", ... } ]
180 , returning = Projection orderId
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list