If the command is a SELECT> statement, the values of the
result columns are placed into Tcl variables named after the columns.
If the -array> option is given, the column values are
- instead stored into the named associative array, with the
- column names used as array indexes.
+ instead stored into elements of the named associative array, with the
+ column names used as array indexes. In addition, the current row
+ number within the result (counting from zero) is stored into the array
+ element named .tupno>
, unless that name is
+ in use as a column name in the result.
If the command is a SELECT> statement and no loop-body>
script is given, then only the first row of results are stored into
- Tcl variables; remaining rows, if any, are ignored. No storing occurs
- if the
- query returns no rows. (This case can be detected by checking the
- result of spi_exec.) For example:
+ Tcl variables or array elements; remaining rows, if any, are ignored.
+ No storing occurs if the query returns no rows. (This case can be
+ detected by checking the result of spi_exec.)
+ For example:
spi_exec "SELECT count(*) AS cnt FROM pg_proc"
-
will set the Tcl variable $cnt> to the number of rows in
the pg_proc> system catalog.
If the optional loop-body> argument is given, it is
a piece of Tcl script that is executed once for each row in the
query result. (loop-body> is ignored if the given
- command is not a SELECT>.) The values of the current row's columns
- are stored into Tcl variables before each iteration. For example:
-
+ command is not a SELECT>.)
+ The values of the current row's columns
+ are stored into Tcl variables or array elements before each iteration.
+ For example:
spi_exec -array C "SELECT * FROM pg_class" {
elog DEBUG "have table $C(relname)"
}
-
will print a log message for every row of pg_class>. This
feature works similarly to other Tcl looping constructs; in
particular continue> and break> work in the
The return value from a trigger procedure can be one of the strings
- OK> or SKIP>, or a list as returned by the
- array get> Tcl command. If the return value is OK>,
- the operation (INSERT>/UPDATE>/DELETE>) that fired the trigger will proceed
+ OK> or SKIP>, or a list of column name/value pairs.
+ If the return value is OK>,
+ the operation (INSERT>/UPDATE>/DELETE>)
+ that fired the trigger will proceed
normally. SKIP> tells the trigger manager to silently suppress
the operation for this row. If a list is returned, it tells PL/Tcl to
- return a modified row to the trigger manager. This is only meaningful
+ return a modified row to the trigger manager; the contents of the
+ modified row are specified by the column names and values in the list.
+ Any columns not mentioned in the list are set to null.
+ Returning a modified row is only meaningful
for row-level BEFORE> INSERT> or UPDATE>
- triggers for which the modified row will be inserted instead of the one
+ triggers, for which the modified row will be inserted instead of the one
given in $NEW>; or for row-level INSTEAD OF>
INSERT> or UPDATE> triggers where the returned row
- is used to support INSERT RETURNING> and
- UPDATE RETURNING> commands. The return value is ignored for
- other types of triggers.
+ is used as the source data for INSERT RETURNING> or
+ UPDATE RETURNING> clauses.
+ In row-level BEFORE> DELETE> or INSTEAD
+ OF> DELETE> triggers, returning a modified row has the same
+ effect as returning OK>, that is the operation proceeds.
+ The trigger return value is ignored for all other types of triggers.
+
+ The result list can be made from an array representation of the
+ modified tuple with the array get> Tcl command.
+
+
+
Here's a little example trigger procedure that forces an integer value
in a table to keep track of the number of updates that are performed on the
Oid typioparam;
FmgrInfo finfo;
- /************************************************************
- * Ignore ".tupno" pseudo elements (see pltcl_set_tuple_values)
- ************************************************************/
- if (strcmp(ret_name, ".tupno") == 0)
- continue;
-
/************************************************************
* Get the attribute number
+ *
+ * We silently ignore ".tupno", if it's present but doesn't match
+ * any actual output column. This allows direct use of a row
+ * returned by pltcl_set_tuple_values().
************************************************************/
attnum = SPI_fnumber(tupdesc, ret_name);
if (attnum == SPI_ERROR_NOATTRIBUTE)
+ {
+ if (strcmp(ret_name, ".tupno") == 0)
+ continue;
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_COLUMN),
errmsg("unrecognized attribute \"%s\"",
ret_name)));
+ }
if (attnum <= 0)
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
CONST84 char *nullname = NULL;
/************************************************************
- * Prepare pointers for Tcl_SetVar2() below and in array
- * mode set the .tupno element
+ * Prepare pointers for Tcl_SetVar2() below
************************************************************/
if (arrayname == NULL)
{
{
arrptr = &arrayname;
nameptr = &attname;
+
+ /*
+ * When outputting to an array, fill the ".tupno" element with the
+ * current tuple number. This will be overridden below if ".tupno" is
+ * in use as an actual field name in the rowtype.
+ */
snprintf(buf, sizeof(buf), "%d", tupno);
Tcl_SetVar2(interp, arrayname, ".tupno", buf, 0);
}