Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Update documentation, and fix a bug in 8.4.

It seems we changed element type in domain type for array.
  • Loading branch information...
commit 7233da1fef288987fb5d46c2470e8e6683871d4d 1 parent db84508
Hitoshi Harada umitanuki authored
Showing with 145 additions and 44 deletions.
  1. +70 −2 doc/plv8.md
  2. +18 −0 expected/plv8.out
  3. +44 −42 plv8_type.cc
  4. +13 −0 sql/plv8.sql
72 doc/plv8.md
View
@@ -18,8 +18,11 @@ Implemented features are as follows.
- Subtransaction
- Utility functions
- Window function API
+- Typed array
+- Remote debugger
- Runtime environment separation across users in the same session
- Start-up procedure
+- Dialects
Scalar function calls
---------------------
@@ -155,12 +158,15 @@ automatically. If the desired database type is one of
- date
- timestamp
- timestamptz
+- bytea
- json (>= 9.2)
and the JS value looks compatible, then the conversion succeeds. Otherwise,
PL/v8 tries to convert them via cstring representation. An array type is
supported only if the dimention is one. A JS object will be mapped to
-a tuple when applicable.
+a tuple when applicable. In addition to these types, PL/v8 supports
+polymorphic types such like anyelement and anyarray. Conversion of bytea is
+a little different story. See TypedArray section.
Database access via SPI including prepared statements and cursors
-----------------------------------------------------------------
@@ -293,7 +299,9 @@ been registered in the database.
With plv8.find_function(), you can look up other plv8 functions. If they are
not the plv8 function, it errors out. The function signature parameter to
plv8.find_function() is either of regproc (function name only) or regprocedure
-(function name with argument types).
+(function name with argument types). You can make use of internal type for
+arguments and void type for return type for the pure JavaScript function to
+make sure any invocation from SQL statement should not happen.
The plv8 object provides version string as `plv8.version`. This string
corresponds to plv8 module version. Note this is not the extension version.
@@ -360,6 +368,54 @@ test, which implements most of the native window functions. For the general
information of the user-defined window function, see the CREATE FUNCTION
page of the PostgreSQL manual.
+Typed array
+-----------
+
+The typed array is something v8 provides to allow fast access to native memory,
+mainly for the purpose of their canvas support in browsers. PL/v8 uses this
+to map bytea and various array types to JavaScript array. In case of bytea,
+you can access each byte as an array of unsigned bytes. For
+int2/int4/float4/float8 array type, PL/v8 provides direct access to each
+element by using PL/v8 domain types.
+
+- plv8_int2array maps int2[]
+- plv8_int4array maps int4[]
+- plv8_float4array maps float4[]
+- plv8_float8array maps float8[]
+
+These are only annotations that tell PL/v8 to use fast access method instead of
+regular one. For these typed arrays, only 1-dimensional array without NULL
+element. Also, there is currently no way to create such typed array inside
+PL/v8 functions. Only arguments can be typed array. You can modify the element
+and return the value. An example for these types are as follows.
+
+ CREATE FUNCTION int4sum(ary plv8_int4array) RETURNS int8 AS $$
+ var sum = 0;
+ for (var i = 0; i < ary.length; i++) {
+ sum += ary[i];
+ }
+ return sum;
+ $$ LANGUAGE plv8 IMMUTABLE STRICT;
+
+ SELECT int4sum(ARRAY[1, 2, 3, 4, 5]);
+ int4sum
+ ---------
+ 15
+ (1 row)
+
+Remote debugger
+---------------
+
+PL/v8 supports v8 remote debugger. You need to enable it at the compile time
+to pass ENABLE_DEBUGGER_SUPPORT to `make`. `make static` will automatically
+turns it on. If enabled, and once PL/v8 module is loaded (and the execution
+engine is initialized, PL/v8 accepts a remote debugger connection. If you
+have `d8` from v8 package, run with `--remote-debug --debug-port=35432` to
+attach the functions. If you want to change the remote debugger port, there
+is a GUC `plv8.debugger_port` to set the port number. You can also try
+`debugger` statement inside functions to set a breakpoint. For more details
+of v8 remote debugger, see v8 documentation.
+
Runtime environment separation across users in the same session
---------------------------------------------------------------
@@ -395,3 +451,15 @@ visible from any subsequent function as global variables.
Remember CREATE FUNCTION also starts the plv8 runtime environment, so make sure
to SET this GUC before any plv8 actions including CREATE FUNCTION.
+
+Dialects
+--------
+
+This module also contains some dialect supports. Currently, we have two dialects
+are supported.
+
+- CoffeeScript (plcoffee)
+- LiveScript (plls)
+
+With PostgreSQL 9.1 or above, you are able to load tohse dialects via CREATE
+EXTENSION command.
18 expected/plv8.out
View
@@ -329,6 +329,24 @@ SELECT polymorphic(ARRAY[10, 11]), polymorphic(ARRAY['foo', 'bar']);
10 | foo
(1 row)
+-- typed array
+CREATE FUNCTION fastsum(ary plv8_int4array) RETURNS int8 AS
+$$
+ sum = 0;
+ for (var i = 0; i < ary.length; i++) {
+ sum += ary[i];
+ }
+ return sum;
+$$
+LANGUAGE plv8 IMMUTABLE STRICT;
+SELECT fastsum(ARRAY[1, 2, 3, 4, 5]);
+ fastsum
+---------
+ 15
+(1 row)
+
+SELECT fastsum(ARRAY[NULL, 2]);
+ERROR: NULL element, or multi-dimension array not allowed in external array type
-- elog()
CREATE FUNCTION test_elog(arg text) RETURNS void AS
$$
86 plv8_type.cc
View
@@ -61,59 +61,61 @@ plv8_fill_type(plv8_type *type, Oid typid, MemoryContext mcxt)
get_type_category_preferred(typid, &type->category, &ispreferred);
get_typlenbyvalalign(typid, &type->len, &type->byval, &type->align);
- if (type->category == TYPCATEGORY_ARRAY)
+ if (get_typtype(typid) == TYPTYPE_DOMAIN)
{
- Oid elemid = get_element_type(typid);
-
- if (elemid == InvalidOid)
- {
- HeapTuple tp;
- Form_pg_type typtup;
+ HeapTuple tp;
+ Form_pg_type typtup;
#if PG_VERSION_NUM < 90100
- tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0);
+ tp = SearchSysCache(TYPEOID, ObjectIdGetDatum(typid), 0, 0, 0);
#else
- tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
+ tp = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typid));
#endif
- if (HeapTupleIsValid(tp))
+ if (HeapTupleIsValid(tp))
+ {
+ /*
+ * Check if the type is the external array types.
+ */
+ typtup = (Form_pg_type) GETSTRUCT(tp);
+ if (strcmp(NameStr(typtup->typname),
+ "plv8_int2array") == 0)
+ {
+ type->ext_array = kExternalShortArray;
+ }
+ else if (strcmp(NameStr(typtup->typname),
+ "plv8_int4array") == 0)
+ {
+ type->ext_array = kExternalIntArray;
+ }
+ else if (strcmp(NameStr(typtup->typname),
+ "plv8_float4array") == 0)
+ {
+ type->ext_array = kExternalFloatArray;
+ }
+ else if (strcmp(NameStr(typtup->typname),
+ "plv8_float8array") == 0)
{
- /*
- * Check if the type is the external array types.
- */
- typtup = (Form_pg_type) GETSTRUCT(tp);
- if (strcmp(NameStr(typtup->typname),
- "plv8_int2array") == 0)
- {
- type->ext_array = kExternalShortArray;
- }
- else if (strcmp(NameStr(typtup->typname),
- "plv8_int4array") == 0)
- {
- type->ext_array = kExternalIntArray;
- }
- else if (strcmp(NameStr(typtup->typname),
- "plv8_float4array") == 0)
- {
- type->ext_array = kExternalFloatArray;
- }
- else if (strcmp(NameStr(typtup->typname),
- "plv8_float8array") == 0)
- {
- type->ext_array = kExternalDoubleArray;
- }
-
- ReleaseSysCache(tp);
+ type->ext_array = kExternalDoubleArray;
}
- if (type->ext_array)
- return;
+ ReleaseSysCache(tp);
+ }
+ else
+ elog(ERROR, "cache lookup failed for type %d", typid);
- /*
- * Otherwise, we don't know how to handle it.
- */
+ if (type->ext_array)
+ return;
+
+ /* If not, do as usual. */
+ }
+
+ if (type->category == TYPCATEGORY_ARRAY)
+ {
+ Oid elemid = get_element_type(typid);
+
+ if (elemid == InvalidOid)
ereport(ERROR,
(errmsg("cannot determine element type of array: %u", typid)));
- }
type->typid = elemid;
get_typlenbyvalalign(type->typid, &type->len, &type->byval, &type->align);
13 sql/plv8.sql
View
@@ -181,6 +181,19 @@ $$
LANGUAGE plv8;
SELECT polymorphic(ARRAY[10, 11]), polymorphic(ARRAY['foo', 'bar']);
+-- typed array
+CREATE FUNCTION fastsum(ary plv8_int4array) RETURNS int8 AS
+$$
+ sum = 0;
+ for (var i = 0; i < ary.length; i++) {
+ sum += ary[i];
+ }
+ return sum;
+$$
+LANGUAGE plv8 IMMUTABLE STRICT;
+SELECT fastsum(ARRAY[1, 2, 3, 4, 5]);
+SELECT fastsum(ARRAY[NULL, 2]);
+
-- elog()
CREATE FUNCTION test_elog(arg text) RETURNS void AS
$$
Please sign in to comment.
Something went wrong with that request. Please try again.