1# PLV8 Built-ins
2
3PLV8 includes a number of built-in functions bound to the `plv8` object for you
4to use.
5
6## Utility Functions
7
8### `plv8.elog`
9
10`plv8.elog` emits a message to the client or the PostgreSQL log file.  The
11emit level is one of:
12
13* `DEBUG5`
14* `DEBUG4`
15* `DEBUG3`
16* `DEBUG2`
17* `DEBUG1`
18* `LOG`
19* `INFO`
20* `NOTICE`
21* `WARNING`
22* `ERROR`
23
24```
25var msg = 'world';
26
27plv8.elog(DEBUG1, 'Hello', `${msg}!`);
28```
29
30See the [PostgreSQL manual](https://www.postgresql.org/docs/current/static/runtime-config-logging.html#RUNTIME-CONFIG-SEVERITY-LEVELS) for information on each error level.
31
32### `plv8.quote_literal`, `plv8.nullable`, `plv8.quote_ident`
33
34Each function for the quote family is identical to the built-in SQL function
35with the same name.
36
37### `plv8.find_function`
38
39PLV8 provides a function to access other functions defined as `plv8` functions
40that have been registered in the database.
41
42```
43CREATE FUNCTION callee(a int) RETURNS int AS $$ return a * a $$ LANGUAGE plv8;
44CREATE FUNCTION caller(a int, t int) RETURNS int AS $$
45  var func = plv8.find_function("callee");
46  return func(a);
47$$ LANGUAGE plv8;
48```
49
50With `plv8.find_function()``, you can look up other PLV8 functions. If they
51are not a PLV8 function, and error is thrown. The function signature parameter
52to `plv8.find_function()`` is either of `regproc` (function name only) or
53`regprocedure` (function name with argument types). You can make use of the
54internal type for arguments and void type for return type for the pure Javascript
55function to make sure any invocation from SQL statements should not occur.
56
57### `plv8.version`
58
59The `plv8` object provides a version string as `plv8.version`.  This string
60corresponds to the `plv8` module version.
61
62## Database Access via SPI
63
64PLV8 provides functions for database access, including prepared statements,
65and cursors.
66
67### `plv8.execute`
68
69`plv8.execute(sql [, args])`
70
71Executes SQL statements and retrieves the results.  The `sql` argument is
72required, and the `args` argument is an optional `array` containing any arguments
73passed in the SQL query.  For `SELECT` queries, the returned value is an `array`
74of `objects`.  Each `object` represents one row, with the `object` properties
75mapped as column names.  For non-`SELECT` queries, the return result is the
76number of rows affected.
77
78```
79var json_result = plv8.execute('SELECT * FROM tbl');
80var num_affected = plv8.execute('DELETE FROM tbl WHERE price > $1', [ 1000 ]);
81```
82
83### `plv8.prepare`
84
85`plv8.prepare(sql [, typenames])`
86
87Opens or creates a prepared statement.  The `typename` parameter is an `array`
88where each element is a `string` that corresponds to the PostgreSQL type name
89for each `bind` parameter.  Returned value is an object of the `PreparedPlan` type.
90This object must be freed by `plan.free()` before leaving the function.
91
92```
93var plan = plv8.prepare('SELECT * FROM tbl WHERE col = $1', [ 'int' ]);
94var rows = plan.execute([ 1 ]);
95var sum = 0;
96for (var i = 0; i < rows.length; i++) {
97  sum += rows[i].num;
98}
99plan.free();
100
101return sum;
102```
103
104### `PreparedPlan.execute`
105
106`PreparedPlan.execute([ args ])`
107
108Executes the prepared statement.  The `args` parameter is the same as what would be
109required for `plv8.execute()`, and can be omitted if the statement does not have
110any parameters.  The result of this method is also the same as `plv8.execute()`.
111
112### `PreparedPlan.cursor`
113
114`PreparedPlan.cursor([ args ])`
115
116Opens a cursor form the prepared statement.  The `args` parameter is the same as
117what would be required for `plv8.execute()` and `PreparedPlan.execute()`.  The
118returned object is of type `Cursor`.  This must be closed by `Cursor.close()`
119before leaving the function.
120
121```
122var plan = plv8.prepare('SELECT * FROM tbl WHERE col = $1', [ 'int' ]);
123var cursor = plan.cursor([ 1 ]);
124var sum = 0, row;
125while (row = cursor.fetch()) {
126    sum += row.num;
127}
128cursor.close();
129plan.free();
130
131return sum;
132```
133
134### `PreparedPlan.free`
135
136Frees the prepared statement.
137
138### `Cursor.fetch`
139
140`Cursor.fetch([ nrows ])`
141
142When the `nrows` parameter is omitted, fetches a row from the cursor and returns
143it as an `object` (note: not as an `array`).  If specified, fetches as many rows
144as the `nrows` parameter, up to the number of rows available, and returns an
145`array` of `objects`.  A negative value will fetch backward.
146
147### `Cursor.move`
148
149`Cursor.move(nrows)`
150
151Moves the cursor `nrows`.  A negative value will move backward.
152
153### `Cursor.close`
154
155Closes the `Cursor`.
156
157### `plv8.subtransaction`
158
159`plv8.subtransaction(func)`
160
161`plv8.execute()` creates a subtransaction each time it executes.  If you need
162an atomic operation, you will need to call `plv8.subtransaction()` to create
163a subtransaction block.
164
165```
166try{
167  plv8.subtransaction(function(){
168    plv8.execute("INSERT INTO tbl VALUES(1)"); // should be rolled back!
169    plv8.execute("INSERT INTO tbl VALUES(1/0)"); // occurs an exception
170  });
171} catch(e) {
172  ... execute fall back plan ...
173}
174```
175
176If one of the SQL execution in the subtransaction block fails, all of operations
177within the block are rolled back. If the process in the block throws a Javascript
178exception, it is carried forward. So use a `try ... catch` block to capture it and
179do alternative operations if it occurs.
180
181## Window Function API
182
183You can define user-defined window functions with PLV8. It wraps the C-level
184window function API to support full functionality. To create one, first obtain a
185window object by calling `plv8.get_window_object()`, which provides the following
186interfaces:
187
188### `WindowObject.get_current_position`
189
190Returns the current position in the partition, starting from `0`.
191
192### `WindowObject.get_partition_row_count`
193
194Returns the number of rows in the partition.
195
196### `WindowObject.set_mark_position`
197
198`WindowObject.set_mark_position(pos)`
199
200Sets the mark at the specified row.  Rows above this position will be gone and
201no longer accessible later.
202
203### `WindowObject.rows_are_peers`
204
205`WindowObject.rows_are_peers(pos1, pos1)`
206
207Returns `true` if the rows at `pos1` and `pos2` are peers.
208
209### `WindowObject.get_func_arg_in_partition`
210
211`WindowObject.get_func_arg_in_partition(argno, relpos, seektype, mark_pos)`
212
213### `WindowObject.get_func_arg_in_frame`
214
215`WindowObject.get_func_arg_in_frame(argno, relpos, seektype, mark_pos)`
216
217Returns the value of the argument in `argno` (starting from 0) to this function
218at the `relpos` row from `seektype` in the current partition or frame.
219`seektype` can be either of `WindowObject.SEEK_HEAD`, `WindowObject.SEEK_CURRENT`,
220or `WindowObject.SEEK_TAIL`. If `mark_pos` is `true`, the row the argument is
221fetched from is marked. If the specified row is out of the partition/frame, the
222returned value will be undefined.
223
224
225### `WindowObject.get_func_arg_in_current`
226
227`WindowObject.get_func_arg_in_current(argno)`
228
229Returns the value of the argument in `argno` (starting from 0) to this function
230at the current row. Note that the returned value will be the same as the argument
231variable of the function.
232
233### `WindowObject.get_partition_local`
234
235`WindowObject.get_partition_local([ size ])`
236
237Returns partition-local value, which is released at the end of the current
238partition. If nothing is stored, undefined is returned. size argument (default
2391000) is the byte size of the allocated memory in the first call. Once the memory
240is allocated, the size will not change.
241
242### `WindowObject.set_partition_local`
243
244`WindowObject.set_partition_local(obj)`
245
246Stores the partition-local value, which you can retrieve later with
247`get_partition_local()``. This function internally uses `JSON.stringify()` to\
248serialize the object, so if you pass a value that is not able to be serialized
249it may end up being an unexpected value. If the size of a serialized value is
250more than the allocated memory, it will throw an exception.
251
252You can also learn more on how to use these API in the `sql/window.sql`
253regression test, which implements most of the native window functions. For
254general information on the user-defined window function, see the [CREATE FUNCTION page of the PostgreSQL manual](https://www.postgresql.org/docs/current/static/sql-createfunction.html).
255