Routine resolution refers to the process that the database server uses when you invoke a routine. The database server also invokes routine resolution when another routine invokes a UDR. If the routine is overloaded, the query parser resolves the UDR from the system catalog tables, based on its routine signature. The parser performs any routine resolution necessary to determine which UDR to execute.
When a user or another routine invokes a routine, the database server searches for a routine signature that matches the routine name and arguments. If no exact match exists, the database server searches for a substitute routine, as follows:
For more information, see Candidate List of Routines.
For more information, see Precedence List of Data Types.
The database server finds a list of candidate routines from the sysprocedures system catalog table that have the following characteristics:
If the candidate list does not contain a UDR with the same data type as an argument specified in the routine invocation, the database server checks for the existence of cast routines that can implicitly convert the argument to a data type of the parameter of the candidate routines.
For example, suppose you create the following two casts and two routines:
CREATE IMPLICIT CAST (type1 AS type2) CREATE IMPLICIT CAST (type2 AS type1) CREATE FUNCTION g(type1, type1) ... CREATE FUNCTION g(type2, type2) ...
Suppose you invoke function g with the following statement:
EXECUTE FUNCTION g(a_type1, a_type2)
The database server considers both functions as candidates. The routine-resolution process selects the function g(type1, type1) because the leftmost argument is evaluated first. The database server executes the second cast, cast(type2 AS type1), to convert the second argument before the function g(type1, type1) executes.
For more information about casting, refer to Creating User-Defined Casts.
To determine which routine in the candidate list might be appropriate to an argument type, the database server builds a precedence list of data types for the argument. The routine-resolution process builds a precedence list, which is a partially ordered list of data types to match. It creates the precedence list as follows (from highest to lowest):
For more information, refer to Routine Resolution with User-Defined Data Types.
If the source type is itself a distinct type, the database server checks the source type of that distinct type. For more information, refer to Routine Resolution with Distinct Data Types.
For more information, refer to Precedence List for Built-In Data Types.
If a match exists in this built-in data type precedence list, the database server searches for an implicit cast function.
If no qualifying routine exists, the database server returns the following error message:
-674: Routine routine-name not found.
If the routine-resolution process locates more than one qualifying routine, the database server returns this error message:
-9700: Routine routine-name cannot be resolved.
If a routine invocation contains a data type that is not included in the candidate list of routines, the database server tries to find a candidate routine that has a parameter contained in the precedence list for the data type. Table 4 lists the precedence for the built-in data types when an argument in the routine invocation does not match the parameter in the candidate list.
Data Type | Precedence List |
---|---|
CHAR | VARCHAR, LVARCHAR |
VARCHAR | None |
NCHAR | NVARCHAR |
NVARCHAR | None |
SMALLINT | INT, INT8, DECIMAL, SMALLFLOAT, FLOAT |
INT | INT8, DECIMAL, SMALLFLOAT, FLOAT, SMALLINT |
INT8 | DECIMAL, SMALLFLOAT, FLOAT, INT, SMALLINT |
SERIAL | INT, INT8, DECIMAL, SMALLFLOAT, FLOAT, SMALLINT |
SERIAL8 | INT8, DECIMAL, SMALLFLOAT, FLOAT, INT, SMALLINT |
DECIMAL | SMALLFLOAT, FLOAT, INT8, INT, SMALLINT |
SMALLFLOAT | FLOAT, DECIMAL, INT8, INT, SMALLINT |
FLOAT | SMALLFLOAT, DECIMAL, INT8, INT, SMALLINT |
MONEY | DECIMAL, SMALLFLOAT, FLOAT, INT8, INT, SMALLINT |
DATE | None |
DATETIME | None |
INTERVAL | None |
BYTE | None |
TEXT | None |
The following example shows overloaded test functions and a query that invokes the test function. This query invokes the function with a DECIMAL argument, test(2.0). Because a test function for a DECIMAL argument does not exist, the routine-resolution process checks for the existence of a test function for each data type that the precedence list in Table 4 shows.
CREATE FUNCTION test(arg1 INT) RETURNING INT... CREATE FUNCTION test(arg1 MONEY) RETURNING MONEY.... CREATE TABLE mytab (a real, ... SELECT * FROM mytab WHERE a=test(2.0);
Figure 2 shows the order in which the database server performs a search for the overloaded function, test(). The database server searches for a qualifying test() function that takes a single argument of type INTeger.