add_="tvf"
<do action_="sql" add_="tvf"> adds a
new table-valued function to a specified schema.
Description
add_="tvf" adds a new table-valued function (TVF) named
[FUNCTION] with type signature [SIGNATURE] to a
specified schema. A given function may be added to a schema multiple times with distinct
signatures.
You can specify the definition of the table-valued function for a given signature with
add_="tvf". The definition must be written in MDB macro language.
However, you can use <code language_="python">, <code
language_="sql">, or <code language_="r"> within macro
language to incorporate other languages into the TVF. <code
language_="macro"> is the default language and may be omitted.
The macro language for the TVF is specified by including it wrapped in
<quote> in the body of <do action_="sql">, or by
specifying it as a list of XML values in the src_ argument. The macro
language may refer to @params_.[NAME], which contains a
literal representation of each argument, or to
@sqlvalues_.[NAME], which contains an MDB expression
evaluating to the argument. In addition,
@sqltypes_.[NAME] contains a string representing the
actual SQL type of the passed argument. See System block variables for more information about
@params_, @sqlvalues_, and
@sqltypes_.
Syntax
<dynamic>
<do action_="sql" add_="tvf"
schema_="[SCHEMA]"
objname_="[FUNCTION]"
signature_="[SIGNATURE]"
priority_="[first|last]"
params_="[PARAMNAMES]"
names_="[names|labels]"/>
</dynamic>
Attributes for add_="tvf"
schema_- The schema where the table-valued function is to be added.
objname_- The name of the function to be added.
signature_- The arguments of the function, supplied as a list of type names separated by either
commas or semicolons, such as
"{'text','integer','integer'}".Possible type names are as follows:
integerdoublebigintbooleantextvarchardatetimestamptimeintervalytm(integer months)intervaldts(fractional days)
signature_="{{'integer','bigint'},{'integer','bigint'}}"means that the function takes two arguments, and each argument can be either an integer or a bigint.A given function may be added to the schema multiple times with distinct signatures. By default, signatures are matched sequentially when the function is called, unless you use the optional
priority_argument. If no signature matches the function's arguments, the table-valued function returns an error. priority_- An optional argument assigning a priority to the signature for the function, in the
case where there is more than one table-valued function in a schema with the same name
but distinct signatures. Possible values are
"first"and"last"("last"is the default value). params_- Specifies the parameter names to be referred to in the definition. It must be a list the same length as the signature containing valid variable names.
names_- An optional argument that may be used to specify that the result of the MDB query
should be imported into SQL using MDB column names instead of column labels
(
"labels"is the default value).
Example
The following example shows how to add a simple table-valued function
"foo" to a schema. The TVF has two signatures: the first signature
accepts one argument, a string, and the second signature accepts three arguments, two
strings and a third argument of any data type. Since it has two signatures, the TVF accepts
either an MDB table path ("path") or an MDB table path
("path") and a column name ("col") and value
("val") to select in that column. For each signature, the result of the
MDB query is imported into SQL using MDB column names. The use of
<quote> prevents premature expansion of the macro code. The
table-valued function code uses @params_.path and
@params_.col because these strings must appear in their raw (unquoted)
form in the expanded MDB query. The TVF also uses @sqlvalues_.val because
an MDB expression is required here.
<do action_="sql" add_="tvf" schema_="myschema" objname_="foo" signature_="string"
params_="path" names_="names">
<quote>
<base table="{@params_.path}"/>
</quote>
</do>
<do action_="sql" add_="tvf" schema_="myschema" objname_="foo" signature_="string;string;"
params_="path;col;val" names_="names">
<quote>
<base table="{@params_.path}"/>
<sel value="{@params_.col}={@sqlvalues_.val}"/>
</quote>
</do>
The TVF "foo" may then be used in the FROM or JOIN clauses of queries, as
follows:
SELECT * FROM myschema.foo('pub.demo.weather.stations');
SELECT * FROM myschema.foo('pub.demo.weather.stations','state','NY');
SELECT name||', '||state as "City", AVG(temp) as "Avg noon temp"
FROM myschema.foo('pub.demo.weather.stations','tz',-5)
JOIN myschema.foo('pub.demo.weather.hourly90','hour',12) USING (id)
GROUP BY 1;
<do action_="sql"
reload_="catalog"/> if you want to test the TVF in the same session.