# Administration Guide

# Extending Database Support

This chapter explains how to extend the database support of Oracle Data Service Integrator. Extensions let you provide immediate, dynamic support for unsupported databases and new versions of supported databases. This chapter explains how to extend database support using a feature called the Configurable Relational Provider.

Tip: | A sample Configurable Relational Provider file is provided in this chapter. You can copy the sample and use it as a starting point for creating your own customized provider. See Sample Configurable Relational Provider File for the complete listing.

This chapter assumes that you are familiar with XQuery and SQL, especially for more advanced use cases. For suggested background on these subjects with respect to Oracle Data Service Integrator, see Related Reading.

This chapter includes these topics:

- Introduction
- Sample Configurable Relational Provider File
- Using the Configurable Relational Provider
- Configurable Relational Provider Format Description and Reference
- Database Matching
- Specifying SQL Syntax for Functions
- Default SQL Syntax for Functions
- Translating Built-In XQuery Operators Into SQL
- Standard and Oracle Data Service Integrator Namespaces for Functions and Types
- Function and Type Name Resolution Process
- Abstract SQL Providers

## Introduction

The Configurable Relational Provider lets you extend the database support and functionality of Oracle Data Service Integrator. The Configurable Relational Provider lets you add or modify database support by configuring an XML file, called a “provider.” You can configure the XML provider to extend database support for all but a few advanced cases. See Using the Configurable Relational Provider for details.

This section describes the overall framework for extending Oracle Data Service Integrator database support, defines general terms, and lists several use cases for the extension framework.

This section includes these topics:

- General Use Cases
- Overview of the Extension Framework Architecture
- Relational Providers Included With Oracle Data Service Integrator
- Supported Features
- Importing Relational Source Metadata
- Related Reading

### General Use Cases

This section explains cases where you might consider extending database support using the Configurable Relational Provider.

- Case 1: Adding extended RDMBS support for your database or, if extended support is provided, customizing or extending that support further.

If you are using Oracle Data Service Integrator with base platform database support (see Relational Providers Included With Oracle Data Service Integrator), it is possible that the database itself can handle more complex constructs, such as expressions and clauses, than are generated by the base platform provider. In this case, users might experience reduced performance. To solve this problem, you can configure an Configurable Relational Provider.

- Case 2: Adding support for a new version of a core database.

If a new version of a core database is released, Oracle Data Service Integrator by default treats it the same as the previously supported version. Obviously, with a new release, there may be features that you want to use, such as improved SQL pushdown. In this case, you can update the database support by extending the relational provider for the core database using the Configurable Relational Provider to add the new pushdown features.

- Case 3: Adding support for a new database that has fewer capabilities than the base platform or is not supported by the core databases.

Note: | This use case is uncommon.

It is possible that you require access to a database that is not supported by Oracle Data Service Integrator core database set (see Table 10-1) and that cannot consume SQL generated by the base platform provider. In this case, you can use the Configurable Relational Provider and either disable unsupported features or add new features as desired.

### Overview of the Extension Framework Architecture

The Relational Wrapper Extension Framework lets you add or modify relational database support for Oracle Data Service Integrator. This framework supports the Configurable Relational Provider, which lets you extend database support by editing a configuration file. Figure 10-1 illustrates the architecture of the Relational Wrapper Extension Framework.

Figure 10-1 Database Extension Framework Architecture

This framework includes a component called a Relational Wrapper that exposes XQuery views of relational sources and executes queries against them. The Relational Wrapper includes the Relational Database Provider Registry, which manages chains of components called relational providers.

Tip: | The Configurable Relational Provider, which is discussed in detail in this chapter, is an example of a relational provider that you can easily configure and deploy by editing a file. The Configurable Relational Provider is the primary means by which you can extend database support.

- Defines the SQL and runtime capabilities of a specific database.
- Allows Oracle Data Service Integrator to handle different databases and their SQL dialects.
- Returns information about runtime and SQL generation capabilities of the database supported by the provider.
- Can be extended to add support for new databases and customize support for existing ones.

Inside the provider registry, relational providers are organized into chains. These chains delegate to one another and allow method invocations to be intercepted and processed along the way. Each provider either answers a request or delegates the request to its parent provider. A provider’s parent is specified by the <parent> element of the provider’s deployment descriptor (see Configurable Relational Provider Format Description and Reference).

As shown in Figure 10-1, the first chain is assembled from three providers: provider_1, provider_2 and provider_3. When the relational wrapper calls this chain, provider_1 first receives the call and has a choice of either answering it or delegating to its parent provider (provider_2). If provider_1 delegates to provider_2 then it is the responsibility of provider_2 to handle the request. In turn, provider_2 can decide to delegate processing to provider_3. This chain architecture increases system flexibility by supporting modular provider definitions and facilitating easy assembly.

Tip: | Typically, when you create a provider using the Configurable Relational Provider, you specify a parent provider. The parent provides some features that the child provider can either accept by default or override. The child provider inherits the features of the parent; however, you can also add features to the child provider that are not implemented in the parent. Usually, one of the abstract providers serves as the parent of the first provider in a chain. See Abstract SQL Providers.

By default, the Relational Wrapper Extension Framework supports a core set of databases. See Relational Providers Included With Oracle Data Service Integrator for a complete list. Extensibility allows for full support of databases that are not in the core set and allows for support of new versions of the core databases. For example, a new version of a core database might provide new pushdown capabilities that are not currently recognized by Oracle Data Service Integrator. You can use the extension framework to add the required database support immediately by editing and deploying a Configurable Relational Provider.

### Relational Providers Included With Oracle Data Service Integrator

Table 10-1 lists the set of standard relational providers that are included with Oracle Data Service Integrator. Standard providers are implemented using the Relational Wrapper Extension Framework and are registered by default. You can use these providers as a basis for configuring the Configurable Relational Provider.

Table 10-1 Relational Providers Included With Oracle Data Service Integrator
Provider ID | Supported Database Type and Version(s) | Base Database Version (Decimal)
--- | --- | ---
Oracle-8 | Oracle >= 8 | 8
Oracle-9 | Oracle >= 9 | 9
MSSQL-2000 | Microsoft SQL Server >= 2000 | 8 Version 8 is the product version returned by the JDBC drivers for SQL Server 2000.
DB2-8 | IBM DB2 >= 8 | 8
Sybase-12.5.2 | Sybase >= 12.5.2 | 12.52
Pointbase | Pointbase >= 5.1 | 5.1
Access | Microsoft Access 2003 Microsoft Access support is implemented using the Configurable Relational Provider described in Using the Configurable Relational Provider. | 4
AbstractSQL, AbstractSQL89, AbstractSQL92 | These abstract providers provide base functionality to the Configurable Relational Provider. See Configurable Relational Provider Format Description and Reference for details. See also Abstract SQL Providers. | Not applicable. The abstract providers do not match any databases, and therefore do no return a base version.

Tip: | The Base Database Version is calculated by the framework. This value specifies the minimum version of a database that a provider can handle. Matching rules are used to determine the value when you pick a provider that best matches your database. For more information on this calculation, see Database Matching.

### Supported Features

The Configurable Relational Provider supports the following features found in the core relational providers:

- Database matching
- Standard JDBC type mapping
- Join pushdown specification
- Clause pushdown specification
- Function and operator pushdown
- Cast pushdown
- Auto-generation of fields (usually keys)
- Stored procedure configuration
- A subset of runtime properties

Some features defined by the Relational Wrapper Extension Framework are not supported by the Configurable Relational Provider. In such cases, the Configurable Relational Provider delegates the request to its parent provider, which answers it.

The unsupported features include:

- Data type mapping
- Data type based matching when pushing down functions and cast operations
- SQL expression kind matching when pushing down functions and cast operations

### Importing Relational Source Metadata

You can import metadata on the data sources needed by your application using the Oracle Data Service Integrator Metadata Import wizard. This wizard introspects available data sources and identifies data objects that can be rendered as data services and functions. The relational provider registry returns a list of providers that best match the database. You can then pick one of these providers (typically, the best match or one close to the best match) from a drop down menu.

The best match appears at the top of the drop down menu. Once created, physical data services become the building-blocks for queries and logical data services. For detailed information on using the Metadata Import wizard, see Creating and Updating Physical Data Services in the Data Services Developer’s Guide. For information on how matching is performed, see Rules for Database Matching.

### Related Reading

Refer to the following Oracle Data Service Integrator documentation for more information on Oracle Data Service Integrator database, XQuery, and SQL support:

- XQuery Engine and SQL in the XQuery and XQSE Developer’s Guide.
- XQuery-SQL Mapping Reference in the XQuery and XQSE Developer’s Guide
- “Supported Relational Database Management Systems” in Oracle Data Service Integrator Supported Configurations

## Sample Configurable Relational Provider File

Listing 10-1 shows a sample Configurable Relational Provider file. This sample demonstrates a possible way to configure a custom Microsoft Access provider. You can also find the sample Microsoft Access provider in your Oracle Data Service Integrator installation here:

    <ALDSP_HOME>/samples/RelationalAdapter/MS-Access

Tip: | Copy this sample provider to use as a starting point for creating your own customized provider. Reference information in this chapter explains all of the configurable elements of this XML file. To get started, see Using the Configurable Relational Provider.

Listing 10-1 Sample Configurable Relational Provider File for a Microsoft Access Database

    <?xml version="1.0"?>
    <aldsp-rdb-extension xmlns="http://www.bea.com/ns/aldsp/rdb/extension">

        <name>MS Access XML Provider</name>
        <vendor>Oracle</vendor>
        <implementation-version>1.0</implementation-version>
        <description> MS Access Relational Wrapper Extension </description>

        <rdb-provider>
            <id>MS-Access-2003</id>
            <description>XMLProvider MS Access 2003</description>
            <parent>AbstractSQL</parent>
            <factory
    class="com.bea.dsp.wrappers.rdb.providers.custom.XMLCustomizableProviderFactory>
      <custom-rdb-provider
        xmlns="http://www.bea.com/ns/aldsp/rdb/extension/custom"
        xmlns:fn="http://www.w3.org/2004/07/xpath-functions"
        xmlns:fn-bea="http://www.bea.com/xquery/xquery-functions"
        xmlns:op-bea="http://www.bea.com/xquery/xquery-operators"
        xmlns:op="http://www.w3.org/2004/07/xpath-operators"
        xmlns:xdt="http://www.w3.org/2004/07/xpath-datatypes"
        xmlns:xs="http://www.w3.org/2001/XMLSchema">

        <database-kind>
         <match-database>
           <![CDATA[
           (jdbc:getDatabaseProductName() eq "ACCESS") and
           (jdbc:getDatabaseMajorVersion() ge 4)
           ]]>
         </match-database>
         <base-version>4</base-version>
        </database-kind>

        <database-objects>
         <catalog quote="&quot;" separator="." />
         <schema quote="&quot;" separator="." />
         <table quote="&quot;" qualified-name-parts="catalog schema table" />
        </database-objects>

        <joins inner-join="true" outer-join="true">
         <sql92 right-trees="true">
          <inner-join-syntax>
           {0} INNER JOIN {1} ON {2}
          </inner-join-syntax>
         </sql92>
        </joins>

        <orderby column="true" expression="true" aggregate="true" null-order="low"/>

        <groupby column="true" expression="true" constant="true"/>

        <subqueries in-from="true" in-where="true" />

        <case supported="false" />

        <functions>

         <!-- String Functions -->
         <function name="fn:concat" supported="true" infix="true" >&amp;</function>
         <function name="fn:string-length" arity="1">LEN({0})</function>
         <function name="fn:lower-case"      arity="1">IIF(ISNULL(LCASE({0})),'',LCASE({0}))</function>
         <function name="fn:upper-case" supported="true" >      IIF(ISNULL(UCASE({0})),'',UCASE({0}))</function>
         <function name="fn:substring" arity="2" >      IIF(ISNULL(MID({0},{1})),'',MID({0},{1}))</function>
         <function name="fn:substring" arity="3" >      IIF(ISNULL(MID({0},{1},{2})),'',MID({0},{1},{2}))</function>

         <function name="fn-bea:left" >LEFT({0},{1})</function>
         <function name="fn-bea:right" >RIGHT({0},{1})</function>
         <function name="fn-bea:repeat" supported="false" />
         <function name="fn-bea:trim" arity="1" >TRIM({0})</function>
         <function name="fn-bea:trim-left" arity="1" >LTRIM({0})</function>
         <function name="fn-bea:trim-right" >RTRIM({0})</function>
         <function name="fn-bea:sql-like" arity="2" >({0} LIKE {1})</function>
         <function name="fn-bea:sql-like" arity="3" supported="false" />
         <function name="fn:starts-with" supported="false" />
         <function name="fn:ends-with" supported="false" />
         <function name="fn:contains" supported="false" />
         <function name="op-bea:string-not-equal" arity="2" >({0} &lt;&gt;      {1})</function>

         <!-- Numeric Functions -->
         <function name="fn:abs" supported="true" arity="1" >ABS({0})</function>
         <function name="fn:ceiling" supported="false" />
         <function name="fn:floor" supported="false" />
         <function name="fn:round" >ROUND ({0})</function>

         <!-- Aggregate Functions -->
         <function name="fn:count" supported="true" arity="1" >COUNT({0})</function>
         <function name="fn:avg" >AVG({0})</function>
         <function name="fn:min" arity="1" >MIN({0})</function>
         <function name="fn:max" supported="true" arity="1" >MAX({0})</function>
         <function name="fn:sum" arity="1" >      IIF(ISNULL(SUM({0})),0,SUM({0}))</function>

         <!-- DateTime Functions -->
         <function name="fn:day-from-date" arity="1" >DAY({0})</function>
         <function name="fn:month-from-date" >MONTH({0})</function>
         <function name="fn:year-from-date" >YEAR({0})</function>
         <function name="fn:day-from-dateTime" arity="1" >DAY({0})</function>
         <function name="fn:month-from-dateTime" >MONTH({0})</function>
         <function name="fn:year-from-dateTime" >YEAR({0})</function>
         <function name="fn:hours-from-dateTime" >HOUR({0})</function>
         <function name="fn:minutes-from-dateTime" arity="1" >MINUTE({0})</function>
         <function name="fn:seconds-from-dateTime" >SECOND({0})</function>
         <function name="fn:current-date" supported="false"/>
         <function name="fn:current-time" supported="false"/>
         <function name="fn:current-dateTime" supported="false"/>

        </functions>

        <casts>
         <cast from="xs:string" from-subtypes="true" to="xs:int">
            CINT({0})
         </cast>
         <cast from="xs:double" from-subtypes="true" to="xs:int">
            CINT({0})
         </cast>
         <cast from="xs:float" from-subtypes="true" to="xs:int">
            CINT({0})
         </cast>
         <cast from="xs:decimal" from-subtypes="true" to="xs:int">
            CINT({0})
         </cast>

         <cast from="xs:string" from-subtypes="true" to="xs:double">
            CDBL({0})
         </cast>
         <cast from="xs:decimal" from-subtypes="true" to="xs:double">
            CDBL({0})
         </cast>
         <cast from="xs:string" from-subtypes="true" to="xs:float">
            CDBL({0})
         </cast>
         <cast from="xs:decimal" from-subtypes="true" to="xs:float">
            CDBL({0})
         </cast>

         <cast from="xs:string" from-subtypes="true" to="xs:dateTime">
            CDATE({0})
         </cast>

         <cast from="xs:float" from-subtypes="true" to="xs:string" >
           CSTR({0})
         </cast>
         <cast from="xs:double" from-subtypes="true" to="xs:string" >
           CSTR({0})
         </cast>
         <cast from="xs:decimal" from-subtypes="true" to="xs:string" >
           CSTR({0})
         </cast>
         <cast from="xs:boolean" from-subtypes="true" to="xs:string" >
           CSTR({0})
         </cast>
         <cast from="xs:dateTime" from-subtypes="false" to="xs:string" >
           CSTR({0})
         </cast>
        </casts>

        <limit>
         <select-top />
        </limit>

        <insert>
         <auto-column-generator kind="sql-post" >
          select @@identity
         </auto-column-generator>
        </insert>

        <properties
          supports-multiple-active-queries-per-connection="false"
          supports-cancel-query="false"
          supports-query-timeout="false" />

       </custom-rdb-provider>
            </factory>
        </rdb-provider>

    </aldsp-rdb-extension>

## Using the Configurable Relational Provider

This section explains how to use the Configurable Relational Provider. The Configurable Relational Provider lets you configure a new relational provider by editing an XML configuration file.

Tip: | Be sure to review the section Introduction before continuing.

This section includes these topics:

- Summary of Basic Configuration Steps
- Deploying the Relational Provider

### Summary of Basic Configuration Steps

This section lists the basic steps required to develop and deploy an Configurable Relational Provider. The basic process of creating a new provider is also shown in Figure 10-2.

Figure 10-2 Custom Provider Development Process

1. Choose a base parent provider, such as one of the Abstract providers discussed in Abstract SQL Providers. The base provider represents the first provider in a provider chain. Subsequent providers in the chain can extend or override features of a parent provider. See Overview of the Extension Framework Architecture for information about provider chains.
2. Configure one or more Configurable Relational Providers. Configurable Relational Providers are configured in an XML file in which you specify all of the properties of the Configurable Relational Provider(s). See Sample Configurable Relational Provider File. The sample is a good starting point for developing your own customized provider.
3. Deploy the provider. A command line script is provided to deploy your customized provider. See Deploying the Relational Provider.
4. Test the provider.

### Deploying the Relational Provider

A command-line deployment tool, described in this section, is provided with Oracle Data Service Integrator. Use this tool to add and remove relational providers. To use this deployment tool, your provider’s deployment descriptor must be packaged in a JAR file.

Note: | When Oracle Data Service Integrator loads an extension, the deployment descriptor is read and validated. If a provider section of the description is determined to be invalid, it is ignored.

#### Adding a Provider

The command syntax for adding a provider is:

    <ALDSP_HOME>/bin/update-providers.[cmd/sh] -add <provider.jar>

The fully-qualified path to the provider relational wrapper extension JAR file is required. When a new provider is added, it is copied into the <ALDSP_HOME>`/providers` directory.

Note: | Adding or removing a provider requires that you restart the IDE or the server.

#### Removing a Provider

The command syntax for removing a provider is:

    <ALDSP_HOME>/bin/update-providers.[cmd/sh] -remove <provider.jar>

Specify the filename of the provider JAR file located in the <ALDSP_HOME>`/providers` directory. When an existing provider is removed, it is deleted from the <ALDSP_HOME>`/providers` directory.

Note: | Adding or removing a provider requires that you restart the IDE or the server.

## Configurable Relational Provider Format Description and Reference

This section describes the format, elements, and configurable properties of an Configurable Relational Provider.

Note: | A complete provider example is listed in Sample Configurable Relational Provider File.

This section includes:

- Overview of Primary XML Elements – This section provides an overview of the top-level elements of the Configurable Relational Provider.
- Overview of the <custom-rdb-provider> Element – This section provides an overview of the <custom-rdb-provider> element. This element contains all of the sub-elements and properties that define a Configurable Relational Provider.
- Configurable Relational Provider Reference – This section describes all of the elements of the <custom-rdb-provider> element.

### Overview of Primary XML Elements

This section describes each of the primary elements in an Configurable Relational Provider file. This file is a deployment descriptor that is used to specify the properties of the relational provider extension.

Tip: | The file must be packaged and deployed in a JAR file. The JAR must only contain one deployment descriptor; however, the descriptor can define and configure one or more providers. See Deploying the Relational Provider.

The following list describes the primary elements of a relational provider deployment descriptor.

Note: | You must name the deployment descriptor file `aldsp-rdb-extension.xml`.

- `<name>` – The name of the provider.
- `<vendor>` – (Optional) The name of the vendor of the provider.
- `<implementation-version>` – (Optional) A version number for the provider.
- `<description>` – (Optional) A brief description of the extension.
- `<id>` – The provider ID. This ID is used to register the provider in the provider registry.
- `<description>` – (Optional) A brief description of the provider.
- `<parent>` – (Optional) The `<id>` element of a parent provider.

Tip: | In the sample file in Sample Configurable Relational Provider File, the class specified by the `<parent>` element is AbstractSQL. See Abstract SQL Providers for detailed information on this abstract provider parent class.

- `<modifier>` – (Optional) Either `abstract` or `final`. If set to `abstract`, the provider cannot be referred to by any data service; however, an abstract provider can be extended (be the parent of another provider). If set to `final`, the provider cannot be extended by any other providers.
- `<factory>` – (Optional) This element specifies a factory class that instantiates the provider. The Configurable Relational Provider uses the default factory class, ,XMLCustomizableProviderFactory.

Tip: | In the sample file in Sample Configurable Relational Provider File, the <factory> element explicitly specifies the default factory class, XMLCustomizableProviderFactory.

- `<custom-rdb-provider>` – A sub-element that specifies the namespace of the Configurable Relational Provider and its full configuration. The default namespace is: http://www.bea.com/ns/aldsp/rdb/extension/custom.

Tip: | For details on configuring the `<custom-rdb-provider>` element, see Sample Configurable Relational Provider File and Configurable Relational Provider Format Description and Reference.

Note: | When Oracle Data Service Integrator loads an extension, the deployment descriptor is read and validated. If a provider section of the description is determined to be invalid, it is ignored.

### Overview of the <custom-rdb-provider> Element

Listing 10-2 shows the basic configuration of the `<custom-rdb-provider>` element in an Configurable Relational Provider. This configuration is based on a schema file that is provided with Oracle Data Service Integrator.

Each of the properties are described in greater detail in Configurable Relational Provider Reference. For a complete example, see Sample Configurable Relational Provider File.

Listing 10-2 Overview of the <custom-rdb-provider> Element

    <custom-rdb-provider xmlns="http://www.bea.com/ns/aldsp/rdb/extension/custom">

        <database-kind>
            <match-database>
                XQuery expression that uses a predefined external function to
                Access JDBC metadata. Result type: boolean
            </match-database>
            <base-version>
                Base database version supported by this provider (decimal)
            </base-version>
            <matched-version>
                XQuery expression returning matched version. Result type: decimal
            </matched-version>
        </database-kind>

        <database-objects>
            <catalog   quote?="string" separator?="string"/>
            <schema    quote?="string" separator?="string" />
            <table     quote?="string" separator?="string"
                                       qualified-name-parts="string*"/>
            <column    quote?="string" />
            <procedure quote?="string" qualified-name-parts="string*"/>
        </database-objects>

        <joins inner-join="boolean" outer-join="boolean">
            <sql92 right-trees="boolean(:=true)" />  or
            <sql89 outer-join-kind?="columnModifier|tableModifier"
                   outer-join-modifier?="string" />
        </joins>

        <orderby column?="boolean" expression?="boolean" aggregate?="boolean"
                 null-order?="low|high|first|last|undefined"
                 style?="ordering-expression|ordering-expression-with-projection|
                    position-in-project-list" />

        <groupby column?="boolean" constant?="boolean" expression?="boolean" />

        <subqueries in-from?="boolean" in-where?="boolean" />

        <case supported?="boolean(:=true)" />

        <functions default-syntax-for-empty-input="lax|strict|strict-coalesce">
            <function name="QName" arity?="integer" supported?="boolean(:=true)"
               infix?="boolean(:=false)">
               SQL expression which uses {0},{1},…{n} for input expressions
               (string)
            </function>
        </functions>

        <casts>
            <cast from="QName" from-subtypes?="boolean(:=false)" to="QName"
                  supported?="boolean(:=true)">
                SQL expression which uses {0} for input expression
            </cast>
        </casts>

        <limit supported?="boolean(:=true)">
            <top parameter="true|false" composable="true|false"/> or
            <rownum kind="project_first|filter_first">
                ROWNUM
            </rownum>
        </limit>

        <insert>
            <key-gen kind?="jdbc|sql-pre|sql-post">
                 SQL statement
            </key-gen>
        </insert>

        <properties
             supports-query-timeout = "boolean"
             supports-cancel-query  = "boolean"
             supports-multiple-active-queries-per-connection = "boolean"
        />

    </custom-rdb-provider>

### Configurable Relational Provider Reference

Table 10-2 describes each of the sub-elements and properties of the `<custom-rdb-provider>` element of an XML Customization Provider configuration file.

For a summary of the file format, see Overview of the <custom-rdb-provider> Element. For a complete example, see Sample Configurable Relational Provider File.

Tip: | Most of the settings listed in Table 10-2 are optional. Any settings that are specified in the configuration file override default settings provided by the parent provider. The parent provider is specified with the `<parent>` element of the descriptor. If no setting is provided for an attribute, then the request is delegated to the parent provider. See Overview of the Extension Framework Architecture for a description of the way in which providers delegate to parent providers in a “chains.”

Table 10-2 Configuration Elements and Attributes Description
Element(s) and Sub-element(s) | Attribute(s) | Description of Element or Attribute
--- | --- | ---
<match-database> <matched-version> |  | These elements contain XQuery expressions that can access JDBC database metadata through predefined external functions. See Database Matching. There are no default values for these elements. Default values are inherited from the parent provider.
<database-objects> |  | Sub-elements of this element specify various properties of database object identifiers in the generated SQL.
<database-objects> <catalog> <schema> <table> <column> <procedure> | quote | The quote attribute specifies the identifier quote for the corresponding database object. Example: <catalog quote=”’” /> To specify open and close quotes, specify first the open quote, then the close quote. Example: <table quote=”[]” /> The general rule is: if the number of characters in the specified quote string is even – then it is assumed that open and close quotes are different. The first half of the specified string is the open quote; the second half is the close quote. If the number of characters in the specified string is odd then it is assumed that the open and close quotes are the same and equal to the whole string.
<database-objects> <catalog> <schema> <table> <procedure> | separator | The separator attribute specifies the separator character between object identifiers in the fully qualified object name. Example: <schema separator=”.”/> If this attribute is not specified, the parent provider’s value is used by default.
<table> <procedure> | qualified-name-parts | The qualified-name-parts attribute specifies a list of object kinds that specify how a fully qualified name is constructed for this database object.
Note: | Object kinds in the list must be separated by a space character.
Example: <table qualified-name-parts=”catalog schema table” /> Example: <procedure qualified-name-parts=”schema procedure”/> If this attribute is not specified, the parent provider’s value is used by default.
<joins> | inner-join outer-join | These attributes are booleans that specify whether the database supports inner and outer joins respectively. The exact join syntax is defined by the sql92 and sql89 child elements of the joins element. Example: <joins inner-join=”true” outer-join=”true”> If these attributes are not specified, the parent provider’s values are used by default.
<joins> <sql92> |  | The sql92 sub-element specifies that the database uses SQL-92 syntax for joins. For example: SELECT ... FROM a INNER JOIN | LEFT OUTER JOIN b ON ...
<joins> <sql92> | right-trees | This attribute is a boolean that determines whether parenthesis can be used to control the order of joins in the join clause. Default: true
<joins> <sql92> | inner-join-syntax | (Optional) Defines the syntax for an inner join. {0} is used for the left branch source, {1} for the right branch source, and {2} for a join condition expression. Example: {0} JOIN {1} ON {2}
<joins> <sql92> | outer-join-syntax | (Optional) Defines the syntax for a left outer join. {0} is used for the left branch source, {1} for the right branch source, and {2} for the join condition expression. Example: {0} LEFT OUTER JOIN {1} ON {2}
<joins> <sql89> |  | The sql89 sub-element specifies that the database uses SQL-89 syntax for joins. For example: SELECT ... FROM a,b WHERE ...
<joins> <sql89> | inner-join-syntax | (Optional) Defines the syntax for a left inner join. {0} is used for the left branch source, {1} for the right branch source. Default: {0}, {1}
<joins> <sql89> | outer-join-syntax | (Optional) Defines the syntax for a left outer join. {0} is used for the left branch source, {1} for the right branch source. Example: {0}, OUTER {1} Default: empty (left outer join is not supported)
<joins> <sql89> | outer-join-right-branch- column-modifier | (Optional) Specifies the transformation to be applied to the columns on the right side of a left outer join. {0} is used to specify the right-side column. Example: {0}(+) Default: empty (no transformation is required)
<orderby> | column expression | This boolean attribute specifies whether the database supports orderby column and other expressions. If these attributes are not specified, the parent provider’s values are used by default.
<orderby> | aggregate | This boolean attribute specifies whether the database supports orderby aggregate.
<orderby> | null-order | This attribute specifies one of the following values: low – NULL values are sorted low. high – NULL values are sorted high. first – NULL values are sorted at the start regardless of sort order. last – NULL values are sorted at the end regardless of sort order. undefined – NULL values are sorted by Oracle Data Service Integrator (“order by” is not pushed to the database in this case). If this attribute is not specified, the parent provider’s values are used by default.
<orderby> | style | Style of the orderby expressions that will be generated: position-in-project-list – Generates ORDER BY n, where 'n' is a position of the ordering expression in the SELECT clause. The ordering expression is automatically added to the SELECT clause if necessary. ordering-expression-with-projection – Generates ORDER BY <expr> where <expr> is automatically added to the SELECT clause if necessary. ordering-expression – Generates ORDER BY <expr> where <expr> is not automatically added to the SELECT clause. There is no default value for this attribute. The parent provider’s value is used if not specified.
<groupby> | column constant expression | These boolean attributes specify whether the group by clause can operate on columns, constants, and expression. If these attributes are not specified, the parent provider’s values are used by default.
<subqueries> | in-from in-where | These boolean attributes specify whether subqueries are supported in FROM and WHERE clauses. Oracle Data Service Integrator generates only a subquery in the WHERE clause only when translating a semi-join. Example: ”WHERE EXITS(...))”) If these attributes are not specified, the parent provider’s values are used by default.
<case> | supported | This boolean attribute specifies whether the CASE expression is supported. Default: true
<functions> |  | This element defines SQL syntaxes for functions.
<functions> | default-syntax-for- empty-input | An enumeration of strings that define which default syntax to use in the presence of NULL input. NULL (an empty sequence in XQuery) input is usually handled differently by SQL and XQuery functions. In SQL, NULL is usually propagate to the output of a function. For example: f(NULL)=NULL). In XQuery, however, NULL is usually replaced with a value. For string functions, such as f( () ) = ””, sum( () )=0, and so on. This setting specifies how to deal with such situations when choosing default SQL syntax for a function. This attribute must specify one of the following values: strict – Follow XQuery semantics. Do not push down if the input can be empty. strict– coalesce – (Default) Follow XQuery semantics. Push down with the help of the COALESCE function in SQL. Only use this value if the database supports the COALESCE function. lax – Do not follow XQuery semantics. Generate SQL without the COALESCE function, such that f(NULL) -> NULL. See Default SQL Syntax for Functions. Default: strict-coalesce
<functions> <function> |  | This sub-element defines the translation of an XQuery function(operator) into SQL. The contents of this sub-element is a SQL expression that must be generated for the named function. Parameters are specified as {0}, {1}, … {n}. A variable number of parameters is supported. See Specifying SQL Syntax for Functions for more information on the format. This element is not required if the supported attribute is set to false. The contents of this element can be empty. In this case, the default syntax for this function is used for SQL generation. A list of default syntaxes is provided in Default SQL Syntax for Functions. For examples, see Sample Configurable Relational Provider File.
<functions> <function> | name | (Required) Specifies the QName of a function. See Function and Type Name Resolution Process.
<functions> <function> | arity | Specifies the arity of the named function. Can be omitted if function name is non-ambiguous.
<functions> <function> | supported | (Boolean) specifies whether the function pushdown is supported or not. Disables the pushdown of a function defined by the parent provider. Default: true
<functions> <function> | infix | (Boolean) Specifies whether or not to use infix formatting style for this function. A SQL expression in the sub-element contents specifies the only infix operation in this case. Parameters are processed automatically.
<casts> |  | This element defines cast operations for push down.
<casts> <cast> |  | Defines translation for cast operations to SQL for a particular combination of types. The content of this element is the SQL expression that must be generated for this cast operation. The parameter is specified as {0}. This element is not required if the supported attribute is false. For examples, see Sample Configurable Relational Provider File.
<casts> <cast> | to from | These attributes specify the QNames of input and target XQuery types. If only a local name is specified, Oracle Data Service Integrator searches for the type in well-known namespaces. For examples, see Sample Configurable Relational Provider File. See also Standard and Oracle Data Service Integrator Namespaces for Functions and Types.
<casts> <cast> | from-subtypes | (Boolean) Specifies whether the matching input type must also match its subtypes (according to XQuery type hierarchy). Default: false. For examples, see Sample Configurable Relational Provider File.
<casts> <cast> | supported | (Boolean) Specifies whether this cast operation is supported. Intended usage is to disable cast pushdown of the parent provider. Default: true
<limit> |  | This element defines the pushdown of fn:subsequence(). This element must have one child element specified. To disable pushdown of this function, set supported to false.
<limit> | supported | (Boolean) Specifies whether the database supports fn:subsequence() pushdown. Default: true
<limit> <select-top> |  | Specifies that fn:subsequence() must be pushed down using the TOP modifier of the SELECT clause. For example: SELECT TOP n FROM ... The content of the select-top element defines SQL syntax for the select clause modifier. {0} is bound to the length expression. Default content value: TOP {0}
<limit> <select-top> | parameter | (Boolean) Specifies whether the TOP value can be a parameter. For example, whether SELECT TOP ? FROM ... is supported by the database. Default: false
<limit> <select-top> | composable | If set to true, specifies whether to stop SQL generation after processing fn:subsequence(). If set to false, continues by creating a subquery for a SELECT TOP ... statement. Default: false
<limit> <row-number- function> |  | Specifies that the fn:subsequence() is a pushdown using a ROWNUM-like function. The content of this element defines the SQL syntax for ROWNUM-like functions supported by the database. The content portion is optional. Default content: ROW_NUMBER() Over(...)
<limit> <row-number- function> | explicit-order-by | (Boolean) Determines whether ORDER BY ordering expressions will be passed as arguments to the ROW_NUMBER function.
<limit> <row-number- function> | split-range-filter | (Boolean) Determines whether the range test should be split between subqueries. (Oracle ROWNUM pattern) Default: false
<limit> <limit-clause> |  | Specifies that fn:subsequence() should be translated into SQL as a LIMIT-like clause added at the end of a SQL query. Content of the <limit-clause> element defines SQL syntax for this clause, where {0} and {1} placeholder bindings depend on the @style attribute (see below). Content value is optional. Default content value: LIMIT {0} OFFSET {1}
<limit> <limit-clause> | kind | Defines kind of the accepted subsequence() function: Range - default - both start and length expression are used. In this case limit clause syntax has {0} parameter bound to the start expression and {1} to the length expression Top - only top-like subsequence() is accepted for pushdown. start expression has to be constant 1. In this case limit clause syntax has only {0} parameter which is bound to the length expression Default value: range
<limit> <limit-clause> | parameter | (Boolean) Specifies whether SQL parameters can be used in limit clause (as start and/or length expressions) Default value: true
<limit> <limit-clause> | composable | (Boolean) Specifies whether SQL generation should stop after processing fn:subsequence() (when set to false), or can continue by creating subquery for SELECT … LIMIT statement (when set to true). Default: false
<limit> <limit-clause> | start-base | Integer. 0 or 1. Defines whether start expression is 0 or 1 - based. Only applicable when @style = range Default: 0
<insert> <auto-column- generator> |  | Defines a strategy to access auto-generated columns when inserting data into the database. Strategy kind is defined by the kind attribute. The content of this element is a SQL expression for certain kinds and empty for others. Example: <insert> <auto-column-generator kind="sql-post"> SELECT LAST_INSERT_ID() </auto-column-generator></insert>
<insert> <auto-column- generator> | kind | A string constant (enumeration) that defines the key generation strategy. This attribute must specify one of the following values: jdbc – (Default) Defines the key generation strategy through the JDBC API. Content of the key-gen element must be empty in this case. sql-pre – Run a specified SQL statement to get the auto-generated key before issuing an INSERT statement. For example, use this attribute to get a key from a sequence-like database object. In this case, the content of the key-gen element is the SQL statement that can use {0} as a placeholder for the sequence object name (specified by the dataservice’s annotation). sql-post – Run a specified SQL statement to get the auto-generated key after an INSERT statement. The content of the key-gen element is the SQL statement that must be executed.
properties |  | The attributes of this element contain various SQL generation and execution properties. These properties do not have default values; the parent’s value is used if a property is not set.
<properties> | multiple-active-queries- per-connection-supported | (Boolean) Specifies whether the database supports multiple active statements open on the same connection.
<properties> | cancel-query-supported | (Boolean) Specifies whether the jdbc.sql.Statement.cancel() method is supported by the database and driver.
<properties> | query-timeout-supported | (Boolean) Specifies whether the jdbc.sql.Statement.setQueryTimeout() method is supported by the database and driver.

## Database Matching

This section describes how Oracle Data Service Integrator determines the best database match for a given provider. Database matching logic is specified as an XQuery expression that can access JDBC database metadata through predefined XQuery external functions.

Matching expressions are specified in the Configurable Relational Provider elements ( Table 10-2, Configuration Elements and Attributes Description, on page 10-21) and are evaluated by the Oracle Data Service Integrator XQuery engine. Expressions can use standard XQuery functions supported by the Oracle Data Service Integrator XQuery engine as well as additional functions defined by the Configurable Relational Provider. Database matching XQuery expressions return an xs:boolean value.

Another use of matching XQuery expressions is to compute the matched database version (in this case the result must be xs:decimal).

This section includes these topics:

- Rules for Database Matching
- JDBC Metadata Methods to XQuery Functions Mapping
- Additional External XQuery Functions

### Rules for Database Matching

The framework employs matching rules to determine if a given provider is compatible with a database. During the metadata import process (see Importing Relational Source Metadata) the relational provider registry determines which providers support the database being imported. For successful matches, the base version offset is also obtained. The base version offset is calculated as:

Base version offset (decimal) = (matched db version – base db version returned by the provider)

Base version decimals for the standard providers are listed in Table 10-1 in the section Relational Providers Included With Oracle Data Service Integrator.

The Datasource Import Wizard uses the base version offset to display providers when there are multiple matches. The wizard’s drop down menu contains providers with the minimum base version offset (that is, the closest version to the database). The best match appears at the top of the drop down menu. For information on the Datasource Import Wizard, see Creating and Updating Physical Data Services in the Data Services Developer’s Guide.

For example, consider the standard DB2 relational provider. This provider matches all DB2 versions starting from 8. Its base version is 8. Assume that a new DB2 provider is created with the Configurable Relational Provider that matches DB2 9 with base version 9. During metadata import of a table from the DB2 9 instance, both providers will match the database. However, for the first provider, the base version offset is 1, but the second one is be 0. Therefore, the second provider will be preferred over the first one.

### JDBC Metadata Methods to XQuery Functions Mapping

This section describes the mapping of a java.sql.DatabaseMetaData instance to a set of XQuery functions that can be used by a database matching expression.

Mapped interface: java.sql.DatabaseMetaData

Function namespace:

- `prefix = jdbc`
- `uri = http://www.bea.com/ns/aldsp/extensions/rdb/providers/custom/jdbc`

Requirements for mapped methods:

- No parameters
- Return type of: boolean, string, or int

Table 10-3 lists the java.sql.DatabaseMetaData methods that satisfy these requirements and their corresponding JDBC methods and XQuery functions.

Table 10-3 Java Method to XQuery Function Mapping
Java Method | XQuery Function
int getDatabaseMajorVersion() | jdbc:getDatabaseMajorVersion() as xs:int?
int getDatabaseMinorVersion() | jdbc:getDatabaseMinorVersion() as xs:int?
String getDatabaseProductName() | jdbc:getDatabaseProductName() as xs:string?
String getDatabaseProductVersion() | jdbc:getDatabaseProductVersion() as xs:string?
int getDriverMajorVersion() | jdbc:getDriverMajorVersion() as xs:int?
int getDriverMinorVersion() | jdbc:getDriverMinorVersion() as xs:int?
String getDriverName() | jdbc:getDriverName() as xs:string?
String getDriverVersion() | jdbc:getDriverVersion() as xs:string?
String getURL() | jdbc:getURL()as xs:string?

Exception handling:

- SQLException, RuntimeException – Rethrows the exception.
- LinkageError – Returns an empty sequence. This exception occurs if the driver is compiled against older version of JDBC API.

### Additional External XQuery Functions

This section describes additional functions that are available in the database matching expression, but are not directly mapped from the jdbc.sql.DatabaseMetaData interface.

Function namespace:

- `prefix = cxp`
- `uri = http://www.bea.com/ns/aldsp/extensions/rdb/providers/custom/`

Table 10-4 lists and describes the function signatures.

Table 10-4 Function Signatures
Function signature | Description
--- | ---
cxp:getDatabaseVersion() as xs:decimal | Returns the database version as xs:decimal. The version is computed based on java.sql.DatabaseMetaData as follows: Try to detect the version from the string returned by the getDatabaseProductVersion() method. Search for a format: n1.n2.n3. n1, n2, n3 must be non-negative integers and n3 is optional. The resulting decimal version is n1+max(n2,99)*0.01+max(n3,999)*0.00001 If Step 1 fails and if getDatabaseMajorVersion(), getDatabaseMinorVersion() are implemented by the driver, then the result is: major + max(minor,99)*0.01
cxp:getDriverVersion() as xs:decimal | Same as approach 1, but uses the following functions from jdbc.sql.DatabaseMetaData: getDriverVersion(), getDriverMajorVersion(), getDriverMinorVersion().

## Specifying SQL Syntax for Functions

This section discusses the SQL syntax for functions specified in the Configurable Relational Provider deployment descriptor. See also Configurable Relational Provider Reference and the example descriptor in Sample Configurable Relational Provider File.

This section includes these topics:

- Syntax Overview
- Setting the infix Attribute
- Using a Variable Length Placeholder

### Syntax Overview

Function SQL syntax is specified as a string with placeholders for each parameter. The syntax defines a SQL fragment to be generated by the relational wrapper when translating the corresponding XQuery function into SQL. It is specified as the content of the `<function>` element.

Example:

    <function name=”fn:lower”>LOWER({0})</functions>

Parameter placeholders start with 0. There can be more than one placeholder with the same index which means that the argument must be replicated in the generated SQL.

Example:

    <function name=”fn:substring” arity=”2”>SUBSTR({0}, {1}, LENGTH({0})-{1}+1) </function>

Functions with a variable number of arguments can be specified in two different ways:

- By setting the `infix` attribute and specifying only a delimiter as the function syntax
- By using a variable length placeholder: `{...}`

These methods are described in the next two sections.

### Setting the infix Attribute

The infix attribute of the function element is set as follows:

    <function name=”fn:concat” infix=”true”>||</function>

The generated SQL for this example is:

    arg1 || arg2 || arg3 || ... || argN

### Using a Variable Length Placeholder

During SQL generation the variable length placeholder `{...}` is replaced with the remaining arguments separated by commas.

    <function name=”fn:concat”>CONCAT({...})</function>

The generated SQL is:

    CONCAT(arg1,arg2,arg3,….,argN)

If another delimiter is required, it must be specified inside the variable length placeholder as follows:

    {...DELIMITER}

For example:

    <function name=”fn:concat”>COALESCE({... || }, ””)</function>

The generated SQL is:

    COALESCE(arg1 || arg2 || arg3 || … || argN, ””)

Note: | In this case the delimiter is “`||` “.

## Default SQL Syntax for Functions

The default syntax for a function is used when the function is specified in the `<functions>` section of the Configurable Relational Provider configuration file (Table 10-2), but its syntax is not provided by the user (the `<function>` element content is empty). For some functions in this case, the relational provider chooses default syntax based on the `default-syntax-for-empty-input` attribute. See Configurable Relational Provider Reference for information on the `default-syntax-for-empty-input` attribute.

This section lists the default syntaxes used for the three possible values of the `default-syntax-for-empty-input` attribute.

Attribute | Described In
strict | Table 10-5
strict-coalesce | Table 10-6
lax | Table 10-7

Functions for which the default SQL syntax depends on the default-syntax-for-empty-input attribute are denoted with an asterisk (*) in Table 10-5, Table 10-6, and Table 10-7.

These functions are:

- fn:concat
- fn:substring with 2 parameters
- fn:substring with 3 parameters
- fn:string-length
- fn:lower-case
- fn:upper-case
- fn:sum

If default syntax is not defined for a function, then you must specify the syntax of the function when you use it. Otherwise, it is an error.

Table 10-5 default-syntax-for-empty-input = strict-coalesce
XQuery function | Default SQL syntax | Pushdown requirements
--- | --- | ---
op:numeric-add | {0} + {1} |
op:numeric-multiply | {0} * {1} |
op:numeric-divide | {0} / {1} |
op:numeric-mod | MOD({0}, {1}) |
fn:abs | ABS({0}) |
fn:ceiling | CEILING({0}) |
fn:floor | FLOOR({0}) |
fn:round | FLOOR({0} + 0.5) |
fn-bea:sql-round | ROUND({0}) |
* fn:concat | COALESCE({0} || {1} || … || {n}, ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Arguments are not of type CLOB or LONG VARCHAR.
* fn:substring ($str, $pos) | if $pos is a subtype of xs:integer COALESCE(SUBSTRING({0} FROM {1}), ‘’) else COALESCE(SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER)), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | First argument is not of type CLOB or LONG VARCHAR.
* fn:substring($str, $pos, $len)`` | if $pos and $len are subtypes of xs:integer COALESCE(SUBSTRING({0} FROM {1} FOR {2}), ‘’) else COALESCE(SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER) FOR CAST({2}+0.5 AS INTEGER)), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | First argument is not of type CLOB or LONG VARCHAR.
* fn:string-length | COALESCE(CHAR_LENGTH({0}), 0) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
* fn:lower-case | COALESCE(LOWER({0}), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
* fn:upper-case | COALESCE(UPPER({0}), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
fn:contains, fn:starts-with, fn:ends-with | LIKE with the ESCAPE clause and ‘|’ as the escape character. | The first argument is not of type CLOB or LONG VARCHAR. The second argument is SQL constant or parameter.
fn:year-from-dateTime, fn:year-from-date | EXTRACT(YEAR FROM {0}) |
fn:month-from-dateTime fn:month-from-date | EXTRACT(MONTH FROM {0}) |
fn:day-from-dateTime fn:day-from-date | EXTRACT(DAY FROM {0}) |
fn:hours-from-dateTime, fn:hours-from-time | EXTRACT(HOUR FROM {0}) |
fn:minutes-from-dateTime, fn:minutes-from-time | EXTRACT(MINUTE FROM {0}) |
fn:seconds-from-dateTime, fn:seconds-from-time | CAST(EXTRACT(SECOND FROM {0}) AS DECIMAL) |
op:hexBinary-equal | {0} = {1} |
op-bea:hexBinary-not-equal | {0} != {1} |
fn:empty | {0} IS NULL |
fn:exists | {0} IS NOT NULL (or as EXISTS if subqueries in the WHERE clause are supported) |
fn:count | COUNT (with COUNT DISTINCT support) |
* fn:sum | COALESCE(SUM({0}), 0) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). |
fn:min | MIN({0}) |
fn:max | MAX({0}) |
fn:avg | AVG({0}) |
fn-bea:sql-like($str, $pattern) | {0} LIKE {1} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:sql-like($str, $pattern, $escape) | {0} LIKE {1} ESCAPE {2} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:left | LEFT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:right | RIGHT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim | LTRIM(RTRIM({0})) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-left | LTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-right | RTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:repeat | REPEAT({0}) | Argument is not of type CLOB or LONG VARCHAR.
* Functions for which the default SQL syntax depends on the `default-syntax-for-empty-input` setting.

Table 10-6 default-syntax-for-empty-input = strict
XQuery function | Default SQL syntax | Pushdown requirements
--- | --- | ---
op:numeric-add | {0} + {1} |
op:numeric-multiply | {0} * {1} |
op:numeric-divide | {0} / {1} |
op:numeric-mod | MOD({0}, {1}) |
fn:abs | ABS({0}) |
fn:ceiling | CEILING({0}) |
fn:floor | FLOOR({0}) |
fn:round | FLOOR({0} + 0.5) |
fn-bea:sql-round | ROUND({0}) |
* fn:concat | {0} || {1} || … || {n} | Arguments are not of type CLOB or LONG VARCHAR. Arguments must be non– nullable (as detected by the compiler).
* fn:substring ($str, $pos) | if $pos is a subtype of xs:integer SUBSTRING({0} FROM {1}) else SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER)) | First argument is not of type CLOB or LONG VARCHAR. First argument must be non– nullable (as detected by the compiler).
* fn:substring($str, $pos, $len) | if $pos and $len are subtypes of xs:integer SUBSTRING({0} FROM {1} FOR {2}) else SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER) FOR CAST({2}+0.5 AS INTEGER)) | First argument is not of type CLOB or LONG VARCHAR. First argument must be non– nullable (as detected by the compiler).
* fn:string-length | CHAR_LENGTH({0}) | Argument is not of type CLOB or LONG VARCHAR. Argument must be non– nullable (as detected by the compiler).
* fn:lower-case | LOWER({0}) | Argument is not of type CLOB or LONG VARCHAR Argument must be non– nullable (as detected by the compiler).
* fn:upper-case | UPPER({0}) | Argument is not of type CLOB or LONG VARCHAR Argument must be non– nullable (as detected by the compiler).
fn:contains, fn:starts-with, fn:ends-with | LIKE with the ESCAPE clause and ‘|’ as escape character. | The first argument is not of type CLOB or LONG VARCHAR. The second argument is SQL constant or parameter.
fn:year-from-dateTime, fn:year-from-date | EXTRACT(YEAR FROM {0}) |
fn:month-from-dateTime fn:month-from-date | EXTRACT(MONTH FROM {0}) |
fn:day-from-dateTime fn:day-from-date | EXTRACT(DAY FROM {0}) |
fn:hours-from-dateTime, fn:hours-from-time | EXTRACT(HOUR FROM {0}) |
fn:minutes-from-dateTime, fn:minutes-from-time | EXTRACT(MINUTE FROM {0}) |
fn:seconds-from-dateTime, fn:seconds-from-time | CAST(EXTRACT(SECOND FROM {0}) AS DECIMAL) |
op:hexBinary-equal | {0} = {1} |
op-bea:hexBinary-not-equal | {0} != {1} |
fn:empty | {0} IS NULL |
fn:exists | {0} IS NOT NULL (or as EXISTS if subqueries in the WHERE clause are supported) |
fn:count | COUNT (with COUNT DISTINCT support) |
`* fn:sum` | SUM({0}) | Argument must be non– nullable (as detected by the compiler).
fn:min | MIN({0}) |
fn:max | MAX({0}) |
fn:avg | AVG({0}) |
fn-bea:sql-like($str, $pattern) | {0} LIKE {1} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:sql-like($str, $pattern, $escape) | {0} LIKE {1} ESCAPE {2} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:left | LEFT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:right | RIGHT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim | LTRIM(RTRIM({0})) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-left | LTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-right | RTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:repeat | REPEAT({0}) | Argument is not of type CLOB or LONG VARCHAR.
* Functions for which the default SQL syntax depends on the `default-syntax-for-empty-input` setting.

Table 10-7 default-syntax-for-empty-input = lax
XQuery function | Default SQL syntax | Pushdown requirements
--- | --- | ---
op:numeric-add | {0} + {1} |
op:numeric-multiply | {0} * {1} |
op:numeric-divide | {0} / {1} |
op:numeric-mod | MOD({0}, {1}) |
fn:abs | ABS({0}) |
fn:ceiling | CEILING({0}) |
fn:floor | FLOOR({0}) |
fn:round | FLOOR({0} + 0.5) |
fn-bea:sql-round | ROUND({0}) |
* fn:concat | {0} || {1} || … || {n} | Arguments are not of type CLOB or LONG VARCHAR.
* fn:substring ($str, $pos) | if $pos is a subtype of xs:integer SUBSTRING({0} FROM {1}) else SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER)) | First argument is not of type CLOB or LONG VARCHAR.
* fn:substring($str, $pos, $len) | if $pos and $len are subtypes of xs:integer SUBSTRING({0} FROM {1} FOR {2}) else SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER) FOR CAST({2}+0.5 AS INTEGER)) | First argument is not of type CLOB or LONG VARCHAR.
* fn:string-length | CHAR_LENGTH({0}) | Argument is not of type CLOB or LONG VARCHAR.
* fn:lower-case | LOWER({0}) | Argument is not of type CLOB or LONG VARCHAR.
* fn:upper-case | UPPER({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn:contains, fn:starts-with, fn:ends-with | LIKE with ESCAPE clause and ‘|’ as escape character | The first argument is not of type CLOB or LONG VARCHAR. The second argument is SQL constant or parameter.
fn:year-from-dateTime, fn:year-from-date | EXTRACT(YEAR FROM {0}) |
fn:month-from-dateTime fn:month-from-date | EXTRACT(MONTH FROM {0}) |
fn:day-from-dateTime fn:day-from-date | EXTRACT(DAY FROM {0}) |
fn:hours-from-dateTime, fn:hours-from-time | EXTRACT(HOUR FROM {0}) |
fn:minutes-from-dateTime, fn:minutes-from-time | EXTRACT(MINUTE FROM {0}) |
fn:seconds-from-dateTime, fn:seconds-from-time | CAST(EXTRACT(SECOND FROM {0}) AS DECIMAL) |
op:hexBinary-equal | {0} = {1} |
op-bea:hexBinary-not-equal | {0} != {1} |
fn:empty | {0} IS NULL |
fn:exists | {0} IS NOT NULL (or as EXISTS if subqueries in the WHERE clause are supported) |
fn:count | COUNT (with COUNT distinct support) |
* fn:sum | SUM({0}) |
fn:min | MIN({0}) |
fn:max | MAX({0}) |
fn:avg | AVG({0}) |
fn-bea:sql-like($str, $pattern) | {0} LIKE {1} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:sql-like($str, $pattern, $escape) | {0} LIKE {1} ESCAPE {2} | Arguments are not of type CLOB or LONG VARCHAR.
fn-bea:left | LEFT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:right | RIGHT({0}, {1}) | First argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim | LTRIM(RTRIM({0})) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-left | LTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-right | RTRIM({0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:repeat | REPEAT({0}) | Argument is not of type CLOB or LONG VARCHAR.
* Functions for which the default SQL syntax depends on the `default-syntax-for-empty-input` setting.

## Translating Built-In XQuery Operators Into SQL

The XQuery Functions and Operators specification defines built-in operators into which arithmetic and comparison operations are translated. For some operations, Oracle Data Service Integrator defines additional operators that it uses for evaluation. These additional operators can also be used for specifying XQuery to SQL translation.

Tip: | For references to the XQuery specifications, see Supported XQuery Specifications in the XQuery and XQSE Developer’s Guide.

For each of the following arithmetic operations, Oracle Data Service Integrator defines more specific operations for the following types: integer, decimal, double, float. These specific operations can be used to specify a better type match when defining a SQL generation rule.

Tip: | The function operation prefixes used in the expanded operations (such as op-bea) are discussed in Standard and Oracle Data Service Integrator Namespaces for Functions and Types.

- op:numeric-add
- op:numeric-subtract
- op:numeric-multiply
- op:numeric-divide
- op:numeric-integer-divide
- op:numeric-mod

For example, the following four operations are defined for op:numeric-add:

- op-bea:integer-add
- op-bea:decimal-add
- op-bea:float-add
- op-bea:double-add

Comparison operations in the XQuery are defined by three operators:

- op:<type>-equals
- op:<type>-less-than
- op:<type>-greater-than

Oracle Data Service Integrator adds three more operations for each type:

- op-bea:<type>-not-equals
- op-bea:<type>-less-than-or-equals
- op-bea:<type>-greater-than-or-equals

For numeric types, each operator op-bea:numeric-<comparison_op> is further expanded into four numeric types:

op-bea:integer-<comparison_op>, op-bea:decimal-<comparison_op>, op-bea:double-<comparison_op>, op-bea:float-<comparison_op>.

Additional numeric comparisons added by Oracle Data Service Integrator follow the same pattern. For example

op-bea:numeric-not-equals is expanded into:

- op-bea:integer-not-equals
- op-bea:decimal-not-equals
- op-bea:double-not-equals
- op-bea:float-not-equals

All six string comparison operators are defined as Oracle Data Service Integrator specific operators:

- op-bea:string-equals
- op-bea:string-less-than
- op-bea:string-greater-than
- op-bea:string-not-equals
- op-bea:string-less-than-or-equals
- op-bea:string-greater-than-or-equals

## Standard and Oracle Data Service Integrator Namespaces for Functions and Types

Table 10-8 lists the standard and Oracle Data Service Integrator namespaces for functions and types. Table 10-9 lists and describes each of the type namespaces.

Table 10-8 Function and operators namespaces
Prefix | Namespace | Description
fn | http://www.w3.org/2004/07/xpath-functions | Standard XQuery functions
op | http://www.w3.org/2004/07/xpath-operators | Standard XQuery operators
fn-bea | http://www.bea.com/xquery/xquery-functions | Oracle Data Service Integrator extension functions
op-bea | http://www.bea.com/xquery/xquery-operators | Oracle Data Service Integrator extension operators

Table 10-9 Type namespaces
Prefix | Namespace | Description
xs | http://www.w3.org/2001/XMLSchema | XML Schema types
xdt | http://www.w3.org/2004/07/xpath-datatypes | Additional XQuery types
dt-bea | http://www.bea.com/xquery/xquery-datatypes | Additional Oracle Data Service Integrator types. Currently only one: dt-bea:numeric (common numeric type)

## Function and Type Name Resolution Process

The Relational Wrapper Extension Framework looks up functions, operators, and types by name as follows:

1. Attempt a lookup using the specified QName. If the object is found, return it.
2. If the namespace is empty or the prefix is not specified, loop through all commonly used namespaces for this object kind (see Standard and Oracle Data Service Integrator Namespaces for Functions and Types) and try to find the object in each of these namespaces.

For example, suppose the following function definition exists:

<function name=”round”>ROUND({0})</function>

First, that name is resolved to a QName in the default element namespace and looked up. Suppose then that the XQuery function with this name is not found (for example, if there was no default namespace used in the XML document). Then the system will try start searching for the following functions (in this order): fn:round, op:round, fn-bea:round, op-bea:round. The system will find fn:round and register it with the specified SQL syntax.

A similar lookup process is applied for types when reading cast operation definitions. For types, the system automatically searches in xs, xdt and dt-bea namespaces.

Note that the `arity` attribute is also optional and only required to disambiguate between functions with the same name, for example, a substring with 2 and 3 arguments.

## Abstract SQL Providers

Oracle Data Service Integrator provides a group of three abstract base classes that provide functionality to the Configurable Relational Provider. The AbstractSQLProvider class is the default parent class of the Configurable Relational Provider. You can specify an abstract provider class in the Configurable Relational Provider’s deployment descriptor with the `parent` element. See Using the Configurable Relational Provider.

This section discusses the abstract relational provider classes, and contains these sections:

- AbstractSQLProvider
- AbstractSQL89Provider
- AbstractSQL92Provider

### AbstractSQLProvider

AbstractSQLProvider is an abstract base class. All other abstract and concrete relational provider classes extend this class. This class is used as a parent provider when the parent is not specified in the deployment descriptor of a provider; therefore, this class is not explicitly registered in the provider registry.

Table 10-10 summarizes the level of SQL support provided by AbstractSQLProvider:

Table 10-10 AbstractSQLProvider Features
Feature | Status
--- | ---
Standard JDBC datatypes | Supported
Trivial select-project queries (for example: select ... from ... where) | Supported
Joins, group by, and order by | Not supported
Catalogs and schemas when addressing tables | Not supported
Catalog, schema, and table quotes | Set to “empty string”
Catalog and schema separator | Set to ‘.’ (although separators are not used for queries generated by this provider)
Runtime properties | All set to false.

Table 10-11 lists the supported functions and operators for AbstractSQLProvider.

Table 10-11 Supported Functions and Operators for AbstractSQLProvider
XQuery function | SQL Syntax | Pushdown Requirements / Comments
--- | --- | ---
and, or, fn:not | AND, OR, NOT | None.
op:numeric-equal op:numeric-less-than op:numeric-greater-than op-bea:numeric-less-than-or-equal op-bea:numeric-greater-than-or-equal op-bea:numeric-not-equal | =, <, >, <=, >=, != |
op-bea:string-equal op-bea:string-less-than op-bea:string-greater-than op-bea:string-less-than-or-equal op-bea:string-greater-then-or-equal op-bea:string-not-equal | =, <, >, <=, >=, != | Both arguments are not CLOB or LONG VARCHAR
op:dateTime-equal op:dateTime-less-than op:dateTime-greater-than op-bea:dateTime-less-than-or-equal op-bea:dateTime-greater-than-or-equal op-bea:dateTime-not-equal | =, <, >, <=, >=, != | None.
op:date-equal op:date-less-than op:date-greater-than op-bea:date-less-than-or-equal op-bea:date-greater-than-or-equal op-bea:date-not-equal | =, <, >, <=, >=, != | None.
op:time-equal op:time-less-than op:time-greater-than op-bea:time-less-than-or-equal op-bea:time-greater-than-or-equal op-bea:time-not-equal | =, <, >, <=, >=, != | None.
op:hexBinary-equal op-bea:hexBinary-not-equal | =, != | Only if both arguments are BINARY or VARBINARY.

### AbstractSQL89Provider

AbstractSQL89Provider extends AbstractSQLProvider (see AbstractSQLProvider). This class adds support for additional clauses, functions, and updates. The AbstractSQL89Provider class includes these features:

- Supports SQL89-style inner joins (for example, `select … from A,B where A.<x> = B.<x>`).
- Supports order by column (null order is assumed to be ‘low’).
- Supports group by column (and aggregate functions).
- Schemas are used for table addressing (using dot as a separator).
- Supports subqueries in where clause.

Table 10-12 lists the supported functions and operators for AbstractSQL89Provider. These functions and operators are in addition to the ones provided by the parent class, AbstractSQLProvider.

Table 10-12 Supported Functions and Operators for AbstractSQL89Provider
XQuery function | SQL Syntax | Pushdown Requirements / Comments
--- | --- | ---
op:numeric-add op:numeric-subtract op:numeric-multiply op:numeric-divide (except op-bea:integer-divide) | +, -, *, / | None.
fn:exists | {0} IS NOT NULL (EXISTS in the WHERE clause is not supported) | None.
fn:empty | {0} IS NULL | None.
fn:count | COUNT (with COUNT DISTINCT support) | None.
fn:sum | SUM({0}) | Note that this function does not match XQuery semantics. For empty (NULL) input, the function returns empty (NULL) instead of 0. XQuery specifies that SUM(())=0; where () is an empty sequence. This provider translates the function to SQL as SUM(...). However, in SQL, SUM(NULL)=NULL, which is equivalent to () in XQuery.
fn:min | MIN({0}) | None.
fn:max | MAX({0}) | None.
fn:avg | AVG({0}) | None.
fn-bea:sql-like($str, $pattern) | {0} LIKE {1} | First argument is not CLOB or LONG VARCHAR. Second (and third) arguments are a SQL constant or parameter.
fn-bea:sql-like($str, $pattern, $escape) | {0} LIKE {1} ESCAPE {2} | None.

### AbstractSQL92Provider

AbstractSQL92Provider extends AbstractSQL89Provider (see AbstractSQL89Provider). This class adds support for SQL92-style joins (inner and outer), subqueries, and other features. The AbstractSQL92Provider class supports:

- Inner and outer-joins
- Subqueries in from clause
- Order by and group by expression
- Case expressions
- Updates (update/identity-fetch – JDBC kind)

Table 10-13 lists the supported functions and operators for AbstractSQL92Provider. These functions and operators are in addition to the ones provided by the parent class, AbtractSQL89Provider.

Table 10-13 Supported Functions and Operators for AbstractSQL92Provider
XQuery function | SQL Syntax | Pushdown Requirements / Comments
--- | --- | ---
fn:concat | COALESCE({0} || {1} || … || {n}, ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Arguments are not of type CLOB or LONG VARCHAR.
fn:upper-case | COALESCE(UPPER({0},’’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
fn:lower-case | COALESCE(LOWER({0},’’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
fn:substring ($str, $pos) | if $pos is a subtype of xs:integer COALESCE(SUBSTRING({0} FROM {1}), ‘’) else COALESCE(SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER)), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | First argument is not of type CLOB or LONG VARCHAR.
fn:substring($str, $pos, $len) | if $pos and $len are subtypes of xs:integer COALESCE(SUBSTRING({0} FROM {1} FOR {2}), ‘’) else COALESCE(SUBSTRING({0} FROM CAST({1}+0.5 AS INTEGER) FOR CAST({2}+0.5 AS INTEGER)), ‘’) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | First argument is not of type CLOB or LONG VARCHAR.
fn:string-length | COALESCE(CHAR_LENGTH({0}), 0) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). | Argument is not of type CLOB or LONG VARCHAR.
fn:contains, fn:starts-with, fn:ends-with | LIKE with ESCAPE clause and ‘|’ as escape character | The first argument is not of type CLOB or LONG VARCHAR. The second argument is SQL constant or parameter.
fn:year-from-dateTime, fn:year-from-date | EXTRACT(YEAR FROM {0}) |
fn:month-from-dateTime fn:month-from-date | EXTRACT(MONTH FROM {0}) |
fn:day-from-dateTime fn:day-from-date | EXTRACT(DAY FROM {0}) |
fn:hours-from-dateTime, fn:hours-from-time | EXTRACT(HOUR FROM {0}) |
fn:minutes-from-dateTime, fn:minutes-from-time | EXTRACT(MINUTE FROM {0}) |
fn:seconds-from-dateTime, fn:seconds-from-time | CAST(EXTRACT(SECOND FROM {0}) AS DECIMAL) |
fn:sum | COALESCE(SUM({0}), 0) COALESCE is not used if at compile-time it is determined that input can never be empty (NULL). SUM(DISTINCT …) is supported |
fn:min | MIN(DISTINCT …) supported |
fn:max | MAX(DISTINCT …) supported |
fn:avg | AVG(DISTINCT … ) supported |
fn-bea:left | SUBSTRING({0} FROM 1 FOR {1}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim | TRIM (BOTH ‘ ‘ FROM {0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-left | TRIM(LEADING ‘ ‘ FROM {0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:trim-right | TRIM(TRAILING‘ ‘ FROM {0}) | Argument is not of type CLOB or LONG VARCHAR.
fn-bea:date-from-dateTime | CAST({0} AS DATE) |

Table 10-14 lists the cast operations that are pushed down by AbstractSQL92Provider.

Table 10-14 Supported Cast Operations for AbstractSQL92Provider
Source Type | Target Type | SQL Syntax | Comments
--- | --- | --- | ---
subtypes of xs:int | xs:string | CAST({0} AS VARCHAR(11)) |
xs:string | xs:double | CAST({0} AS DOUBLE PRECISION) | Argument is not of type CLOB or LONG VARCHAR.
subtypes of numeric | xs:double |
xs:string | xs:float | CAST({0} AS REAL) | Argument is not of type CLOB or LONG VARCHAR.
subtypes of numeric | xs:float |
xs:string | xs:int | CAST({0} AS INT) | Argument is not of type CLOB or LONG VARCHAR.
subtypes of numeric | xs:int |
xs:string | xs:short | CAST({0} AS SMALLINT) | Argument is not of type CLOB or LONG VARCHAR.
subtypes of numeric | xs:short |
xs:dateTime | xs:date | CAST({0} AS DATE) |