This is the multi-page printable view of this section. Click here to print.

Return to the regular view of this page.

JDBC

JDBC for documentation website.

1 - Application Protector - JDBC

JDBC guide for Application Protector 10.0.0.0

This document describes the high-level architecture of the JDBC Protector, the installation procedures, and provides guidance on performance. This document focuses on Protegrity-specific aspects and should be used in conjunction with the corresponding documentation for your cloud provider.

This guide may also be used with the Protegrity Enterprise Security Administrator Guide, which explains the mechanism for managing the data security policy.

1.1 - Introduction

Introduction to the JDBC Protector guide

    This document describes the high-level architecture of the JDBC Protector, the installation procedures, and provides guidance on performance. This document focuses on Protegrity-specific aspects and should be used in conjunction with the corresponding documentation for your cloud provider.

    This guide may also be used with the Protegrity Enterprise Security Administrator Guide, which explains the mechanism for managing the data security policy.

    1.2 - Overview

    Solution overview and features.

      Solution Overview

      The Protegrity JDBC Protector enables Java applications to work with protected data in SQL databases. Installed as a Java Database Connectivity (JDBC) driver, the protector works in conjunction with the application’s existing database driver to make data protection transparent to the application. Java applications may use this driver to access protected data with little or no code changes.

      This protector utilizes a data security policy maintained by a Protegrity Enterprise Security Administrator (ESA), similar to other Protegrity products. Using SQL queries and the JDBC API, Java applications can perform both de-identification (protect) and re-identification (unprotect) operations on data. When setting the current user, privileges will be restricted to the policies defined by the ESA for that user.

      Features

      Combined with an ESA security policy, the Protegrity JDBC Protector provides the following features:

      • Enables JVM-based applications to perform transactions with protected data over JDBC
      • Provides transparent data protection in the JDBC-layer using mapping metadata between protected columns and data elements in the security file
      • Requires minimal application changes to utilize
      • Supports most cloud-managed databases such as:
        • Amazon Aurora
        • Amazon RDS
        • Azure SQL Database
        • Databricks SQL
        • Google Cloud SQL
        • Oracle Autonomous Database
      • Supports most SQL databases such as:
        • Db2 for Linux, Unix and Windows 11.5
        • Db2 for z/OS 12
        • Informix 14.10
        • MariaDB 10.4, 10.5, 10.6
        • MySQL 8.0
        • Oracle Database 19c, 21c
        • PostgreSQL 12, 13, 14, 15, 16
        • SQL Server 2019
      • Supports most application servers such as:
        • Apache Tomcat
        • Tableau Server
        • WildFly

      For more information about the available protection options, such as data types, tokenization, encryption, or length-preserving and non-preserving tokens, refer to the Protection Methods Reference.

      Architecture

      The JDBC Protector is installed into the application’s classpath and is registered as the primary JDBC driver. The protector driver operates in conjunction with the application’s existing native JDBC driver to provide transparent data protection between the application layer and the SQL database. This enables applications to work with protected data in SQL databases with minimal code or configuration modifications.

      The JDBC Protector operates as an in-memory SQL engine for parsing and executing SQL queries through the application’s native driver. It uses a customer-provided JSON file to map protected fields in the SQL database to a security data element. This allows the protector to transparently protect and unprotect data within the JDBC layer. For example, on insert and update statements, the protector will protect data in the clear before it is written to the database. On read, the protector unprotects data before it is returned to the application. For search queries, it will substitute clear search strings with the tokenized equivalent value enabling full pushdown to the database including use of database indexes on protected columns.

      Optimal query processing is pushed down to the underlying database driver in most cases. Certain queries (e.g. wildcard searches on protected data) may require in-memory processing. In such cases, the JDBC Protector will make one or more queries to the underlying database driver to retrieve the required data, and execute the remaining query in memory. This type of operation may involve increased JVM memory, CPU, and latency.

      The JDBC Protector requires the security policy and a user to perform data protection operations. The user can either be a single configured service account or a dynamic user set on the connection by the application. A variety of security policy deployment and provisioning architectures are available. These alternatives are described later in this document.

      Analytics on Protected Data

      Protegrity’s format and length preserving tokenization scheme makes it possible to perform analytics directly on protected data. Tokens are join-preserving so protected data can be joined across datasets. Often statistical analytics and machine learning training can be performed without the need to re-identify protected data. However, a user or service account with authorized security policy privileges may re-identify subsets of data using SQL queries through the JDBC Protector.

      1.3 - Installation

      Install and configure the JDBC Protector into your Java application.

      The JDBC Protector can be integrated into any Java application that utilizes JDBC for connecting to a database. Java programming skills are recommended for understanding the configuration changes required to integrate the JDBC Protector. Users without Java programming skills should start with the SQL Workbench/J section. It contains an example of integrating the JDBC Protector into an application for executing SQL queries against any JDBC-compatible database.

      1.3.1 - Prerequisites

      Requirements before installing the JDBC Protector.

        Prerequisites

        The following prerequisites are required for installing the JDBC Protector:

        • JDBC Protector distribution

        • Java 8, 11, or 17

        • Protegrity ESA 10.0.0 or later

        • For installation on Linux, the following packages are required

          • libc 2.27 or later
          • libgcc 8.4.0 or later
          • libstdc++ 8.4.0 or later
        • For installation on Windows, the Microsoft Visual C++ 2015 Redistributable Package is required

          https://aka.ms/vs/17/release/vc_redist.x64.exe

        Supported Platforms

        The JDBC Protector was tested against the following databases and platforms. It may be compatible with versions not listed below:

        Cloud-managed databases:

        • Amazon Aurora
        • Amazon RDS
        • Azure SQL Database
        • Databricks SQL
        • Google Cloud SQL
        • Oracle Autonomous Database

        Database versions:

        • DB2 for Linux, UNIX, and Windows 11.5
        • DB2 for z/OS 12
        • Informix 14.10
        • MariaDB 10.4, 10.5, 10.6
        • MySQL 8.0
        • Oracle Database 19c, 21c
        • PostgreSQL 12, 13, 14, 15, 16
        • SQL Server 2019

        Required Skills and Abilities

        RoleNotes
        Java ProgrammerConfigures the JDBC driver for the Java application.
        Network AdministratorOpens the firewall to provide access to ESA.
        Protegrity AdministratorAdds a trusted application and provides credentials for downloading the data store.
        System AdministratorInstalls the Protegrity components on the server.

        1.3.2 - Install JDBC Driver

        Configure the Java classpath to include the JDBC Protector.

          Install JDBC Driver

          The JDBC Protector contains a JDBC 4.1 compliant driver. Add the jar files and the cloud-protect.properties file to the Java classpath for your application.

          Deployment Packages

          The JDBC Protector is delivered as an ApplicationProtector_<BUILD>_<RELEASE_VERSION>.zip deployment package on the my.protegrity.com customer portal. Download the package that matches the environment and architecture of the JVM that runs your application. The SRVL packages are intended for serverless runtimes such as AWS Lambda and Azure Functions.

          ArchitectureDeployment packages
          x86-64ApplicationProtector_Linux-ALL-64_x86-64_JDBC-1.8-64_<RELEASE_VERSION>.zip
          ApplicationProtector_WIN-ALL-64_x86-64_JDBC-1.8-64_<RELEASE_VERSION>.zip *
          ApplicationProtector_SRVL-ALL-64_x86-64_AWS.JDBC-1.8-64_<RELEASE_VERSION>.zip
          ApplicationProtector_SRVL-ALL-64_x86-64_Azure.JDBC-1.8-64_<RELEASE_VERSION>.zip
          ARM-64ApplicationProtector_Linux-ALL-64_ARM-64_JDBC-1.8-64_<RELEASE_VERSION>.zip
          ApplicationProtector_SRVL-ALL-64_ARM-64_AWS.JDBC-1.8-64_<RELEASE_VERSION>.zip
          ApplicationProtector_SRVL-ALL-64_ARM-64_Azure.JDBC-1.8-64_<RELEASE_VERSION>.zip

          <RELEASE_VERSION> is the build version of the release, for example ApplicationProtector_Linux-ALL-64_ARM-64_JDBC-1.8-64_10.0.0.303.zip.

          * There is no ARM-64 deployment package for Windows. On Windows on ARM, download the Windows x86-64 package and run your application with an x64 JVM, so that the native library can be loaded through the built-in x64 emulation. An ARM-64 JVM fails to load the library and reports an UnsatisfiedLinkError.

          To install an x64 JVM on Windows on ARM:

          1. Download a Windows x64 build of Java 8, 11, or 17 from your JDK vendor. Do not select the aarch64 build.

          2. Install it to a separate directory, such as C:\Program Files\Java\jdk-17-x64.

          3. Start your application with that JVM and confirm the architecture:

            "C:\Program Files\Java\jdk-17-x64\bin\java.exe" -XshowSettings:properties -version
            

            The output must report os.arch = amd64. If it reports aarch64, the wrong JVM is in use.

          Choose one of the following installation methods based on your application type:

          Classpath Installation

          For general Java applications, copy the required files to your application’s classpath.

          Prerequisites

          • Unzip the release build ApplicationProtector_<BUILD>_<RELEASE_VERSION>.zip
          • Change into the classpath directory inside the unzipped directory

          Steps

          1. Copy the protegrity-jdbc-<version>.jar and the protegrity-protect-<platform>-<version>.jar files to your application.

          2. If your application does not already have an slf4j-api.jar file, copy the provided slf4j-api.jar and slf4j-simple.jar files to your application.

          3. Copy the cloud-protect.properties file to your application.

          Apache Maven Installation

          Install the JDBC driver using Apache Maven.

          Prerequisites

          • Unzip the release build ApplicationProtector_<BUILD>_<RELEASE_VERSION>.zip
          • Change into the maven directory inside the unzipped directory
          • Java and Maven installed
          • Access to a Maven repository

          Steps

          1. Open a terminal inside the maven directory.

          2. Install to the local Maven repository. Run the following commands, replacing the placeholder values.

            mvn install:install-file \
              -Dfile=./iap-jdbc-maven-<RELEASE_VERSION>.jar \
              -DpomFile=./iap-jdbc-maven-<RELEASE_VERSION>-pom.xml
            
            mvn install:install-file \
              -Dfile=./protect-<PLATFORM>-<RELEASE_VERSION>-esa.jar \
              -DpomFile=./protect-<PLATFORM>-<RELEASE_VERSION>-esa-pom.xml \
              -Dclassifier=esa
            
          3. (Optional) Deploy to a Maven repository:

            mvn deploy:deploy-file \
              -DgroupId=com.protegrity.jdbc \
              -DartifactId=iap-jdbc-maven \
              -Dversion=<RELEASE_VERSION> \
              -Dpackaging=jar \
              -Dfile=./iap-jdbc-maven-<RELEASE_VERSION>.jar \
              -DpomFile=./iap-jdbc-maven-<RELEASE_VERSION>-pom.xml \
              -DrepositoryId=<your-repo-id> \
              -Durl=<https://your.maven.repo/url>
            
            mvn deploy:deploy-file \
              -DgroupId=com.protegrity.cloud \
              -DartifactId=protect-<PLATFORM> \
              -Dversion=<RELEASE_VERSION> \
              -Dpackaging=jar \
              -Dfile=./protect-<PLATFORM>-<RELEASE_VERSION>-esa.jar \
              -DpomFile=./protect-<PLATFORM>-<RELEASE_VERSION>-esa-pom.xml \
              -Dclassifier=esa \
              -DrepositoryId=<your-repo-id> \
              -Durl=<https://your.maven.repo/url>
            
          4. Add the deployed artifact to your application’s pom.xml, matching the groupId, artifactId, and version. Example:

            <dependency>
              <groupId>com.protegrity.jdbc</groupId>
              <artifactId>iap-jdbc-maven</artifactId>
              <version><RELEASE_VERSION></version>
            </dependency>
            
            <dependency>
              <groupId>com.protegrity.cloud</groupId>
              <artifactId>protect-<PLATFORM></artifactId>
              <version><RELEASE_VERSION></version>
            

          1.3.3 - Security Policy

          Configure the Protegrity Security Policy for the JDBC Protector.

            Protegrity Security Policy

            The JDBC Protector requires access to a security policy. Several policy deployment architectures are supported as outlined below:

            Policy Sync

            Policy Sync — The JDBC Protector connects directly to an upstream Protegrity server (ESA 10.2.0+) via HTTPS to download the security policy. No separate agent process is required. The policy is cached locally and automatically refreshed. Configured entirely through JDBC connection properties.

            Resilient Deployment Architectures

            These architectures allow an application to function without direct access or dependency on an ESA:

            Cloud API on AWS — The JDBC Protector invokes the Protegrity Cloud API function in AWS Lambda for handling data protection operations.

            Cloud Protect Agent on AWS — A separate, serverless agent process fetches the security policy from ESA. The agent encrypts the file using Amazon KMS and stores it in Amazon S3. The JDBC Protector loads the security policy from S3 and decrypts it in memory using KMS.

            Lambda Layer on AWS — The policy agent publishes the security policy as an AWS Lambda Layer. The JDBC Protector resolves the latest layer version, downloads the content, and extracts the policy package. This is an alternative to the S3-based approach that leverages native Lambda Layer versioning for policy updates.

            Cloud Protect Agent on Azure — A separate, serverless agent process fetches the security policy from ESA. The agent encrypts the file using Azure Key Vault and stores it in Blob Storage. The JDBC Protector loads the security policy from Blob Storage and decrypts it in memory using Azure Key Vault.

            Configuration

            Refer to the following sections for further instructions:

            1.3.3.1 - Policy Sync

            Configure Policy Sync mode for direct policy download from ESA.

            Policy Sync

            The Policy Sync mode downloads the security policy directly from an upstream Protegrity server (ESA 10.2.0+) via HTTPS. It does not require a separate agent process or cloud storage. The policy is cached locally and automatically refreshed at a configurable interval.

            This mode is supported on Linux and Windows.

            Requirements

            • The JDBC Protector must already be installed on the Java classpath. For more information, see Install JDBC Driver.
            • Upstream Protegrity server (ESA) version 10.2.0 or later (RPS API 1.10.0+)
            • Network connectivity to the ESA HTTPS port (typically 443)
            • A user account with Export Resilient Package and Can Create JWT Token permissions

            Configuration

            Policy Sync is configured entirely through JDBC extended connection properties. No cloud-protect.properties file is required.

            Set ptyProtectUri to an rps:// URI pointing to the upstream server:

            PropertyRequiredDefaultDescription
            ptyProtectUriYes—Policy source URI. Use rps://host:port for sync mode
            ptyPolicySyncUsernameYes—Username for JWT authentication
            ptyPolicySyncPasswordYes—Password for JWT authentication
            ptyPolicySyncDatastoreNo—Datastore name (sent as x-pty-datastore header)
            ptyPolicySyncDatastoreKeyYes—SHA-256 fingerprint of the public key matching the KMS decryption key
            ptyPolicySyncInsecureNofalseSkip TLS certificate and hostname verification
            ptyPolicySyncCaCertPathNo—Path to a custom CA certificate (PEM). Disables hostname verification
            ptyPolicySyncTimeoutSecondsNo30HTTP connection and read timeout
            ptyPolicySyncIntervalSecondsNo120Policy refresh interval in seconds
            ptyPolicySyncEmptyStringNo—Core config: empty string representation (e.g. null, empty)
            ptyPolicySyncCaseSensitiveNo—Core config: policy user case sensitivity (yes or no)
            ptyPolicyEncryptionKeyLabelYes—KMS/Key Vault key ARN or URL used to encrypt the policy

            TLS Verification

            ConfigurationCertificate validationHostname verification
            Default (no options)JVM trust store (public CAs)Enabled
            ptyPolicySyncCaCertPath setPinned CA onlyDisabled
            ptyPolicySyncInsecure=trueDisabled (trust all)Disabled

            Use ptyPolicySyncCaCertPath when connecting to a server with a private/internal CA. Use ptyPolicySyncInsecure=true only for development and testing.

            Example: Extended Properties

            PropertyValue
            ptyProtectUrirps://10.0.1.50:443
            ptyPolicySyncUsernamepolicy_admin
            ptyPolicySyncPasswordP@ssw0rd!2026
            ptyPolicySyncDatastorePROD_DATA_STORE
            ptyPolicySyncDatastoreKeyab:cd:12:34:56:78:9a:bc:de:f0:11:22:33:44:55:66:77:88:99:aa:bb:cc:dd:ee:ff:00:11:22:33:44:55:66
            ptyPolicySyncCaCertPath/etc/pki/tls/certs/protegrity-ca.pem
            ptyPolicySyncCaseSensitiveno
            ptyPolicySyncEmptyStringempty
            ptyPolicySyncIntervalSeconds60
            ptyPolicyEncryptionKeyLabelarn:aws:kms:us-east-1:123456789012:key/abcdef01-2345-6789-abcd-ef0123456789

            Example: JDBC URL

            jdbc:iap:postgresql://db.example.com:5432/appdb?user=appuser&password=dbpass;ptyProtectUri=rps://esa.internal.example.com:443;ptyPolicySyncUsername=policy_admin;ptyPolicySyncPassword=P@ssw0rd!2026;ptyPolicySyncDatastore=PROD_DATA_STORE;ptyPolicySyncCaseSensitive=no;ptyPolicySyncInsecure=true
            

            How It Works

            1. On first connection, the JDBC Protector authenticates with the upstream server using JWT.
            2. It checks the server version (minimum 1.10.0 required).
            3. It checks if a policy export is available using If-Modified-Since.
            4. If available, downloads the policy package and caches it to disk.
            5. Writes core.cfg (from ptyPolicySyncEmptyString/ptyPolicySyncCaseSensitive) next to the cached policy.
            6. Loads the policy via the native decoder.
            7. Periodically checks for policy updates (default: every 120 seconds).

            On subsequent connections within the same JVM, the cached ProtectService is reused instantly (no server contact).

            Caching

            • Metadata (~/.pty-sync/sync-metadata.txt): Stores Last-Modified, datastore, and datastore key for If-Modified-Since checks.
            • Policy cache (~/.pty-sync/cached-policy.pkg): Cached policy package for fast reload without re-downloading.
            • Core config (~/.pty-sync/core.cfg): Generated from ptyPolicySyncEmptyString and ptyPolicySyncCaseSensitive. Updated on every policy load to reflect current connection properties.

            If the datastore or datastore key configuration changes, the cache is invalidated and a fresh download is triggered.

            Logging

            The JDBC Protector uses SLF4J for logging. To enable file-based logging, add an SLF4J binding and configuration to your application’s classpath.

            Using SLF4J Simple:

            1. Add slf4j-simple to the classpath.

            2. Create a simplelogger.properties file on the classpath:

            org.slf4j.simpleLogger.defaultLogLevel=info
            org.slf4j.simpleLogger.logFile=protegrity.log
            org.slf4j.simpleLogger.showDateTime=true
            org.slf4j.simpleLogger.dateTimeFormat=yyyy-MM-dd HH:mm:ss.SSS
            org.slf4j.simpleLogger.showShortLogName=true
            
            1. Restart the application. Logs will be written to protegrity.log in the working directory.

            Set defaultLogLevel=debug for verbose output including HTTP request details and cache behavior.

            Comparison with Other Modes

            FeaturePolicy SyncCloud Agent (S3/Blob)
            Requires separate agentNoYes
            Requires cloud storageNoYes (S3 or Blob)
            Requires KMS/Key VaultNoNo (optional)
            Direct ESA connectionYes (HTTPS)No (agent handles it)
            Auto-refreshYesYes (via agent)
            PlatformsLinux, WindowsAWS, Azure

            1.3.3.2 - Cloud API on AWS

            Configure the JDBC Protector to use the Protegrity Cloud API on AWS Lambda.

            Cloud API on AWS

            The JDBC Protector will invoke the Protegrity Cloud API function in AWS Lambda to handle data protection operations. Audit logs will be written by the Protegrity Cloud API function to Amazon CloudWatch.

            Before you begin

            Install the Protegrity Cloud API on AWS. For more information, refer to the Cloud API on AWS guide.

            Configure your Java application

            1. Ensure that your application has access to invoke the Protegrity Cloud API function in AWS Lambda.

              AWS credentials will be loaded from the following sources: environment variables, Java system properties, AWS CLI, and the EC2 role.

            2. Copy the protegrity-protect-aws-<version>.jar file to your Java application.

              See the Install JDBC Driver section for more information.

            3. Create a cloud-protect.properties file and set uri to the Protegrity Cloud API function ARN. This file should be saved with your Java application’s configuration.

              uri=arn:aws:lambda:us-east-1:123456789012:function:Protegrity_Protect_RESTAPI
              

            The following additional configuration options may be added to cloud-protect.properties:

            PropertyDefault valueDescription
            software.amazon.awssdk.defaultsModelegacyProvides optimized default values that align with your application architecture. For more information, refer to the Smart configuration defaults page.
            software.amazon.awssdk.http.maxConnections50Maximum number of simultaneous connections to AWS Lambda. *1
            software.amazon.awssdk.lambda.endpointAllows changing the AWS Lambda endpoint, typically for FIPS compliance. Must start with https://.

            1.3.3.3 - Cloud Protect Agent on AWS

            Configure the JDBC Protector to use the Protegrity Cloud Protect Agent on AWS.

            Cloud Protect Agent on AWS

            The Protegrity Cloud API on AWS will download the policy from your ESA server, encrypt it with AWS KMS, and store it on Amazon S3. The protector will download the policy from S3 and load it into memory. It will poll S3 and reload the policy if changes are detected. Audit logs will be written using the SLF4J logger.

            Before you begin

            Install the Protegrity Cloud API on AWS. For more information, refer to the 3.7 Policy Agent Installation section of the Cloud API on AWS v3.0 guide.

            Configure your Java application

            1. Ensure that your application has access to the AWS KMS key used to encrypt the policy.

              AWS credentials will be loaded from the following sources: environment variables, Java system properties, AWS CLI, and the EC2 role.

            2. Copy the protegrity-protect-aws-<version>.jar file to your Java application.

              See the Install JDBC Driver section for more information.

            3. Create a cloud-protect.properties file and set uri to the policy file in S3. This file should be saved with your Java application’s configuration.

              uri=s3://bucket/protegrity-policy.zip
              

            To use a custom endpoint for Amazon S3, set the following properties in your cloud-protect.properties file:

            PropertyDescription
            software.amazon.awssdk.s3.endpointThe URI of the endpoint for accessing Amazon S3. For example, the FIPS endpoint for us-east-1 is https://s3-fips.us-east-1.amazonaws.com
            software.amazon.awssdk.s3.regionThe name of the region where the S3 bucket is located. For example, set the value to us-east-1 if the bucket is in US East (Virginia).

            1.3.3.4 - Lambda Layer on AWS

            Configure the JDBC Protector to download policy from an AWS Lambda Layer.

            Lambda Layer on AWS

            The Protegrity Cloud API on AWS deploys the policy package to both an S3 bucket and an AWS Lambda Layer. As an alternative to S3, the JDBC Protector can download the policy directly from the Lambda Layer. The protector resolves the latest published version of the layer, downloads the content, extracts the policy package, and loads it into memory. It periodically checks for new layer versions and reloads the policy when updates are detected.

            Before you begin

            • Install the Protegrity Cloud API on AWS (policy agent). The agent must be configured to publish the policy package as a Lambda Layer.
            • Ensure that your application has IAM permissions to call lambda:ListLayerVersions and lambda:GetLayerVersion on the target layer ARN.

            Configure your Java application

            1. Ensure that your application has access to the AWS KMS key used to encrypt the policy.

              AWS credentials are loaded from the default credential provider chain: environment variables, Java system properties, AWS CLI profile, ECS task role, or EC2 instance role.

            2. Copy the protegrity-protect-aws-<version>.jar file to your Java application.

              See the Install JDBC Driver section for more information.

            3. Configure the Lambda Layer ARN using one of the methods below.

            Option A: Connection properties

            Set ptyProtectUri to the Lambda Layer ARN (without a version suffix):

            PropertyRequiredDefaultDescription
            ptyProtectUriYes—Lambda Layer ARN, e.g. arn:aws:lambda:us-east-1:123456789012:layer:policy-layer
            ptyPolicyEncryptionKeyLabelYes—AWS KMS key ARN used to decrypt the policy

            Option B: cloud-protect.properties

            Create a cloud-protect.properties file and set uri to the Lambda Layer ARN:

            uri=arn:aws:lambda:us-east-1:123456789012:layer:policy-layer
            

            How It Works

            1. On first connection, the JDBC Protector calls ListLayerVersions to resolve the latest version of the configured layer.
            2. It calls GetLayerVersion to obtain the presigned download URL for the layer content.
            3. Downloads the layer content (a zip archive).
            4. Extracts IMMUTABLE_POLICY_PACKAGE from the zip.
            5. Decrypts and loads the policy into memory using the configured KMS key.
            6. Periodically checks for new layer versions. When a new version is detected, the updated policy is downloaded and loaded.

            On subsequent connections within the same JVM, the cached ProtectService is reused without contacting AWS.

            Example: JDBC URL

            jdbc:iap:postgresql://db.example.com:5432/appdb?user=appuser&password=dbpass;ptyProtectUri=arn:aws:lambda:us-east-1:123456789012:layer:policy-layer;ptyPolicyEncryptionKeyLabel=arn:aws:kms:us-east-1:123456789012:key/abcdef01-2345-6789-abcd-ef0123456789
            

            Example: Extended Properties

            PropertyValue
            ptyProtectUriarn:aws:lambda:us-east-1:123456789012:layer:policy-layer
            ptyPolicyEncryptionKeyLabelarn:aws:kms:us-east-1:123456789012:key/abcdef01-2345-6789-abcd-ef0123456789

            IAM Permissions

            The application’s IAM role or user must have the following permissions on the Lambda Layer:

            {
              "Effect": "Allow",
              "Action": [
                "lambda:ListLayerVersions",
                "lambda:GetLayerVersion"
              ],
              "Resource": "arn:aws:lambda:us-east-1:123456789012:layer:policy-layer"
            }
            

            Additionally, kms:Decrypt permission is required on the KMS key used to encrypt the policy.

            1.3.3.5 - Cloud Protect Agent on Azure

            Configure the JDBC Protector to use the Protegrity Cloud Protect Agent on Azure.

            Cloud Protect Agent on Azure

            The Protegrity Cloud API on Azure will download the policy from your ESA server, encrypt it with Azure Key Vault, and store it in Azure Blob Storage. The protector will download the policy from Storage and load it into memory. It will poll Storage and reload the policy if changes are detected. Audit logs will be written using the SLF4J logger.

            Before you begin

            Install the Protegrity Cloud API on Azure. For more information, refer to the section 3.7 Policy Agent Function App Installation in the Cloud API on Azure v3.0 guide.

            Configure your Java application

            1. Ensure that your application has access to the Azure Key Vault key used to encrypt the policy.

              Azure credentials will be loaded from the following sources: environment variables, managed identity, and the Azure CLI.

            2. Copy the protegrity-protect-azure-<version>.jar file to your Java application.

              See the Install JDBC Driver section for more information.

            3. Create a cloud-protect.properties file and set uri to the policy file in Storage. This file should be saved with your Java application’s configuration.

              uri=https://account.blob.core.windows.net/container/IMMUTABLE_POLICY_PACKAGE
              

            1.3.3.6 -

            Immutable AP Java

            The Immutable Java Application Protector will download the policy from your ESA server, encrypt it, and store it in persistent storage.

            Install the Protegrity Immutable Java Application Protector. For more information, refer to the 2 IAP Deployment Model section of the Application Protector Java Immutable Policy User Guide.

            Configure your Java application:

            1. Copy the protegrity-protect-linux64-<version>.jar (Linux) or the protegrity-protect-win64-<version>.jar (Windows) file to your Java application.

              See the Install JDBC Driver section for more information.

            2. Create a cloud-protect.properties file with uri=rps://esa.example.com:443 as the contents. This file should be saved with your Java application’s configuration.

              You may also specify the path to AP Java. The default installation directory will be used if none is provided.

              • Linux:

                uri=rps://esa.example.com:443:/opt/protegrity/applicationprotector/java
                
              • Windows:

                uri=rps://esa.example.com:443:/C:/Program%20Files/Protegrity/Defiance%20AP/java
                

            1.3.4 - Configure the schema

            Configure the schema for data protection mapping.

              Configure the Schema

              Create a schema.json file to map the database schema to the security policy.

              Refer to the Schema Configuration section for a detailed schema.json description and usage.

              1. Create a schema.json file and save it with your application’s configuration.

              2. Edit the file and describe your database schema. Only protected fields need to be mapped. The following snippet shows an example:

                {"schema":
                    {"database": [
                        {"name": "database or schema name",
                         "table": [
                            {"name": "table name",
                             "column": [
                                {"name": "protected column name",
                                 "dataelement": "data element name"
                                },
                                {"name": "protected column name",
                                 "dataelement": "data element name"
                                }
                            ]}
                        ]}
                    ]}
                }
                
              3. Set the ptyCatalogUri connection property to the path of the file.

                • Use classpath: when the file is in an application configuration directory or a JAR file that has been added to the JVM classpath. For example:

                  classpath:/config/schema.json
                  
                • Use file: when the file is in a local directory. For example:

                  • Linux:

                    file:/path/to/schema.json
                    
                  • Windows:

                    file:///C:/path/to/schema.json
                    

              1.3.5 - Configure the Application

              Configure JDBC Protector integration settings.

              Your application should be reconfigured to use the JDBC Protector driver instead of your database driver. The following sections have steps for some common Java applications.

              For more information on changing your JDBC configuration, refer to the documentation for your Java application.

                Generic JDBC Application

                For applications using the JDBC API, modify the JDBC URL and provide the path to the schema.json file described in the previous section.

                Modify the application as follows:

                1. Insert iap after the jdbc: prefix of the JDBC URL.

                  For example, if the previous JDBC URL was:

                  jdbc:mysql://localhost:3306
                  

                  Change it to:

                  jdbc:iap:mysql://localhost:3306
                  
                2. Add ptyCatalogUri to the JDBC connection properties and provide the path to the schema.json file created in the previous step.

                  For example:

                  properties.setProperty("ptyCatalogUri", "file:/opt/schema.json");
                  

                Here is an example of using the JDBC Protector for connecting to a MySQL server:

                Properties properties = new Properties();
                properties.setProperty("user", "admin");
                properties.setProperty("password", "");
                properties.setProperty("ptyCatalogUri", "file:/opt/schema.json");
                
                Connection connection =
                        DriverManager.getConnection("jdbc:iap:mysql://localhost:3306/db", properties);
                

                For additional JDBC connection properties, see the Connection Properties section.

                Spring Boot

                Applications using Spring Boot should provide application configuration in their application.properties or application.yml file, and then consume the provided configuration to create a JDBC connection or an XA data source as shown below.

                Additional information on XA support can be found here.

                1. Configure the application:

                  protegrity.jdbc.iap.url=jdbc:iap:postgresql://localhost:5432/dbName
                  protegrity.jdbc.postgres.url=jdbc:postgresql://localhost:5432/dbName
                  protegrity.jdbc.postgres.username=user
                  protegrity.jdbc.postgres.password=password
                  protegrity.jdbc.policy=/opt/IMMUTABLE_POLICY_PACKAGE
                  protegrity.jdbc.catalog=/opt/pty-schema.json
                  protegrity.jdbc.policyUser=policy_user
                  protegrity.jdbc.delegateClassName=org.postgresql.xa.PGXADataSource
                  
                2. Consume the application configuration:

                  import com.protegrity.jdbc.JdbcUrl;
                  import com.protegrity.jdbc.xa.ProtegrityXADataSource;
                  import org.springframework.beans.factory.annotation.Value;
                  import org.springframework.context.annotation.Bean;
                  import org.springframework.context.annotation.Configuration;
                  
                  import javax.sql.XADataSource;
                  import java.net.URI;
                  import java.nio.file.Paths;
                  import java.sql.Connection;
                  import java.sql.DriverManager;
                  import java.sql.SQLException;
                  import java.util.Properties;
                  
                  @Configuration
                  public class ApplicationConfiguration
                  {
                      @Value("${protegrity.jdbc.iap.url}")
                      private JdbcUrl iapJdbcUrl;
                  
                      @Value("${protegrity.jdbc.postgres.url}")
                      private JdbcUrl postgresJdbcUrl;
                  
                      @Value("${protegrity.jdbc.postgres.username}")
                      private String username;
                  
                      @Value("${protegrity.jdbc.postgres.password}")
                      private String password;
                  
                      @Value("${protegrity.jdbc.policyUser}")
                      private String policyUser;
                  
                      @Value("${protegrity.jdbc.delegateClassName}")
                      private String delegateClassName;
                  
                      private URI policy;
                      private URI catalog;
                  
                      public ApplicationConfiguration(
                              @Value("${protegrity.jdbc.catalog}") String catalog,
                              @Value("${protegrity.jdbc.policy}") String policy)
                      {
                          this.policy = Paths.get(policy).toUri();
                          this.catalog = Paths.get(catalog).toUri();
                      }
                  
                      @Bean
                      public Connection jdbc() throws SQLException
                      {
                          var properties = new Properties();
                          properties.put("user", username);
                          properties.put("password", password);
                          properties.put("ptyCatalogUri", catalog.toString());
                          properties.put("ptyProtectUri", policy.toString());
                          properties.put("ptyPolicyUser", policyUser);
                  
                          return DriverManager.getConnection(iapJdbcUrl.toString(), properties);
                      }
                  
                      @Bean
                      public XADataSource xa()
                      {
                          // Currently, we only support using Postgres for XA transactions.
                          var properties = new Properties();
                          properties.put(ProtegrityXADataSource.PropertyNames.URL, postgresJdbcUrl);
                          properties.put(ProtegrityXADataSource.PropertyNames.USER, username);
                          properties.put(ProtegrityXADataSource.PropertyNames.PASSWORD, password);
                          properties.put(ProtegrityXADataSource.PropertyNames.CATALOG_URI, catalog.toString());
                          properties.put(ProtegrityXADataSource.PropertyNames.PROTECT_URI, policy.toString());
                          properties.put(ProtegrityXADataSource.PropertyNames.POLICY_USER, policyUser);
                          properties.put(ProtegrityXADataSource.PropertyNames.DELEGATE_CLASS_NAME, delegateClassName);
                  
                          // Pass other non-Protegrity properties by their name
                          properties.put("defaultNullCollation", "low");
                          properties.put("sslmode", "verify-ca");
                  
                          return new ProtegrityXADataSource(properties);
                      }
                  }
                  

                1.3.6 - Set the Policy User

                Configure the policy user for the JDBC Protector.

                  Set the Policy User

                  The JDBC Protector will use the database username as the policy user if no other username is provided. Alternatively, the application can set the policy user for each connection by setting the POLICY_USER variable. An example is provided in the following snippet:

                  connection.createStatement().execute("SET POLICY_USER = 'jon.snow' ");
                  

                  1.3.7 - Set Request ID

                  Configure the request ID for audit logging.

                    Set Request ID

                    The request_id is an optional field for storing metadata in protector audit records. It can be used to correlate application activity with the protector audit records. The request_id can be set for each connection by setting the REQUEST_ID variable. The value is empty until set by the application. This is only supported when using a security policy from a Cloud Protect Agent.

                    connection.createStatement()
                            .execute("SET REQUEST_ID = '01978dbc-0582-d7e4-0000-002a3603a20d' ");
                    

                    1.4 - SQL Workbench/J

                    SQL Workbench/J is a free application for executing SQL queries using any JDBC driver.

                      SQL Workbench/J is a free application for executing SQL queries using any JDBC driver. It can be used with the JDBC Protector to verify and demonstrate its compatibility with supported databases. SQL queries, such as SELECT, INSERT, and UPDATE, can be executed and the results viewed in a table. It is not required when using the JDBC Protector with another application.

                      Users should be familiar with Protegrity software such as ESA and PEP Server, and have a basic understanding of how to use a JDBC driver. Permissions to add a trusted application in ESA may be required.

                      Install the Software

                      SQL Workbench/J is a free application available for Linux, macOS, and Windows. It requires Java in order to run which can be downloaded using the instructions below.

                      Before you begin

                      Install the Protegrity AP Java and PEP Server software for your platform. The cloud-protect.properties file is not required if AP Java is installed into the default location.

                      Download and install SQL Workbench/J:

                      1. Download the SQL Workbench/J generic package for all systems.

                      2. Create a new directory named Workbench and unzip the Workbench-Build128.zip file to this directory.

                      3. Copy the protegrity-jdbc-<version>.jar, protegrity-protect-<platform>-<version>.jar, slf4j-simple-<version>.jar, and slf4j-api-<version>.jar files from the JDBC Protector package to the Workbench directory.

                      4. Download the Java Runtime Environment (JRE) by running the following program from the Workbench directory:

                        • Linux & macOS: Run the download_jre.sh program.
                        • Windows: Right-click the download_jre.cmd file and select Run.

                      Configure the Driver

                      A JDBC driver allows SQL Workbench/J to connect to a specific type of database, such as Oracle or SQL Server. Each JDBC driver will have its own set of JAR file(s) that must be added to the application.

                      Configure your database driver:

                      1. Download the JDBC driver for your database. If it is a ZIP file, unzip the contents and locate the JAR file(s).

                      2. Open SQL Workbench/J by running the following program from the Workbench directory:

                        • Linux & macOS: Run the sqlworkbench.sh program.
                        • Windows: Right-click the SQLWorkbench.exe file and select Open.
                      3. In the Select Connection Profile window, click the Manage Drivers button.

                      4. Click the blank document button to create a new entry.

                      5. Enter a description into the Name field, such as Protegrity JDBC Protector.

                      6. Click the folder button to begin adding files.

                        a. Add the JAR file(s) for your database.

                        b. Add the protegrity-jdbc-<version>.jar, protegrity-protect-<platform>-<version>.jar, slf4j-simple-<version>.jar, and slf4j-api-<version>.jar files.

                      7. If prompted to select a driver, select the com.protegrity.jdbc.Driver option.

                      8. Click OK to close the Manage drivers window.

                      Configure the Profile

                      In SQL Workbench/J, a connection profile contains the configuration necessary to connect to a specific database. Profiles using the JDBC Protector can use connection properties for both the database and the JDBC Protector.

                      Configure a connection profile:

                      1. Click the profile button to create a new entry.

                      2. Replace New profile with a description for your connection profile.

                      3. Change the Driver to the Protegrity JDBC Protector driver you created in the previous section.

                      4. Enter the JDBC URL for your database into the URL field.

                        For more information about JDBC URLs, refer to the documentation for your database.

                      5. Insert iap after the jdbc: prefix in the URL field.

                        For example, if your URL field was:

                        jdbc:mysql://localhost:3306/database
                        

                        Change it to:

                        jdbc:iap:mysql://localhost:3306/database
                        
                      6. Enter the Username and Password for your database into the appropriate fields.

                      7. Save the profile.

                      8. Close SQL Workbench/J, then reopen it.

                      9. Select the profile, then click OK to connect to the database.

                      You can now try entering any SELECT, INSERT, or UPDATE query into the Statement section and clicking the execute button. The results should appear in the Messages section.

                      For more information about error messages and solutions to common issues, refer to the Troubleshooting section.

                      Configure Data Protection

                      Database columns are protected automatically based on the policy defined in a schema.json file. This file maps the columns of a database table to the data element to be used for protect and unprotect operations.

                      Before you begin

                      Create a schema.json file according to the Schema Configuration section.

                      Set the schema for the profile:

                      1. In SQL Workbench/J, click File and select Connect window.

                      2. Select the profile you created previously.

                      3. Click the Extended Properties button.

                      4. Click the blank document button to add a new entry.

                      5. Enter ptyCatalogUri into the Property field (e.g., ‘file:/pty-schema.json’).

                      6. Enter the path to the schema.json file into the Value field.

                      7. Click OK to close the Edit extended properties window.

                      8. Save the profile.

                      9. Close SQL Workbench/J, then reopen it.

                      10. Select the profile, then click OK to connect to the database.

                      You can now try an INSERT query to write data to a protected column. The protected value should appear in the database. A subsequent SELECT query should return the original value.

                      For more information about error messages and solutions to common issues, refer to the Troubleshooting section.

                      Troubleshooting

                      Enabling logging can help in troubleshooting issues when using SQL Workbench/J.

                      Enable logging:

                      1. Open the File menu and select Manage Drivers.

                      2. Select the driver you created, such as Protegrity JDBC Protector.

                      3. Click the folder button to add a file.

                      4. Add the slf4j-simple.jar file.

                        The file can be downloaded from Maven.

                      5. If prompted to select a driver, select the com.protegrity.jdbc.Driver option.

                      6. Click OK to close the Manage drivers window.

                      7. In SQL Workbench/J, open the Tools menu and select Options.

                      8. On the General tab, change the Log Level to DEBUG.

                      9. Make note of the location of the Logfile. When there is a problem with the JDBC Protector, open this file to view the error message.

                      10. Click OK to save the changes.

                      1.5 - DBeaver

                      DBeaver is a free database tool for executing SQL queries using any JDBC driver.

                        DBeaver is a free, cross-platform database tool for executing SQL queries using any JDBC driver. It can be used with the JDBC Protector to verify and demonstrate its compatibility with supported databases. It is not required when using the JDBC Protector with another application.

                        Users should be familiar with Protegrity software such as ESA and PEP Server, and have a basic understanding of how to use a JDBC driver.

                        Install the Software

                        DBeaver Community Edition is available for Linux, macOS, and Windows. It requires Java in order to run (bundled with the installer).

                        Linux

                        Install DBeaver using the package manager:

                        sudo apt-get install dbeaver-ce
                        

                        Or download from the DBeaver website.

                        Windows

                        Download and run the installer from the DBeaver website.

                        Configure the Driver

                        A custom JDBC driver must be configured in DBeaver to use the JDBC Protector.

                        Before you begin

                        Prepare the following files from the JDBC Protector package:

                        • protegrity-jdbc-<version>.jar
                        • protegrity-protect-<platform>-<version>.jar
                        • Database-specific JDBC driver JAR (e.g., postgresql-<version>.jar)

                        Steps

                        1. Open DBeaver and navigate to Database → Driver Manager.

                        2. Click New to create a new driver.

                        3. Fill in the driver settings:

                          FieldValue
                          Driver NameIAP JDBC (PostgreSQL)
                          Class Namecom.protegrity.jdbc.Driver
                          URL Templatejdbc:iap:postgresql://{host}[:{port}]/[{database}]
                          Default Port5432
                        4. Switch to the Libraries tab and click Add File. Add the following JAR files:

                          • protegrity-jdbc-<version>.jar
                          • protegrity-protect-<platform>-<version>.jar
                          • Database JDBC driver JAR (e.g., postgresql-<version>.jar)
                        5. Click OK to save the driver.

                        Create a Connection Profile

                        1. Click Database → New Database Connection.

                        2. Select the IAP JDBC driver created above.

                        3. In the Main tab, configure the connection URL:

                          jdbc:iap:postgresql://host:port/database
                          
                        4. Switch to the Driver properties tab and add the Protegrity connection properties:

                          PropertyDescriptionExample
                          ptyProtectUriProtection service URIrps://esa-host:443
                          ptyPolicySyncHostPolicy sync server host18.234.164.217
                          ptyPolicySyncPortPolicy sync server port443
                          ptyPolicySyncUsernamePolicy sync usernameadmin
                          ptyPolicySyncPasswordPolicy sync password
                          ptyPolicySyncCaCertPathPath to CA certificate PEM file/path/to/ProtegrityCA.pem
                          ptyPolicySyncCaseSensitiveCase sensitivityno
                          ptyPolicySyncEmptyStringEmpty string token nameempty
                          ptyPolicySyncDatastoreKeyDatastore key hash
                          ptyPolicyUserPolicy user for tokenizationmaster_useR
                          ptyPolicyEncryptionKeyLabelKMS key ARN for encryptionarn:aws:kms:...
                          ptyPolicySyncIntervalSecondsPolicy sync interval in seconds30
                          ptyPolicySyncInsecureDisable TLS verificationfalse
                        5. Click Test Connection to verify the configuration.

                        6. Click Finish to save the connection.

                        Logging

                        DBeaver captures JDBC Protector log messages in its debug log:

                        • Linux: ~/.local/share/DBeaverData/workspace6/.metadata/dbeaver-debug.log
                        • Windows: %APPDATA%\DBeaverData\workspace6\.metadata\dbeaver-debug.log

                        For detailed stack traces, check the Eclipse platform log:

                        • Linux: ~/.local/share/DBeaverData/workspace6/.metadata/.log
                        • Windows: %APPDATA%\DBeaverData\workspace6\.metadata\.log

                        Troubleshooting

                        Invalid JDBC URL

                        Symptom: Invalid JDBC URL: jdbc:iap:postgresql://...

                        Solution: Ensure the connection uses the custom IAP JDBC driver (not the built-in PostgreSQL driver). Check that the provider is set to the custom driver in the connection settings.

                        No Protegrity protect service provider found for URI

                        Symptom: No Protegrity protect service provider found for URI: rps://...

                        Solution: The protegrity-protect-<platform>-<version>.jar (ESA) is missing from the driver libraries. Add it to the driver configuration.

                        Class not found: com.protegrity.cloud.protect.ProtectFactory

                        Symptom: Class definition not found: com/protegrity/cloud/protect/ProtectFactory

                        Solution: The ESA JAR is missing. Add protegrity-protect-<platform>-<version>.jar to the driver libraries.

                        No suitable JDBC driver found

                        Symptom: No suitable JDBC driver found for URL: jdbc:postgresql://...

                        Solution: The underlying database JDBC driver is missing. Add the database-specific driver JAR (e.g., postgresql-<version>.jar) to the IAP JDBC driver libraries.

                        Missing “uri” in protect configuration properties

                        Symptom: Missing "uri" in protect configuration properties

                        Solution: Add the ptyProtectUri property to the connection’s driver properties, or create a cloud-protect.properties file with uri=rps://host on the driver classpath.

                        1.6 - Upgrading to the Latest Version

                        Instructions for upgrading to the latest version of JDBC Protector

                          Upgrading to the Latest Version

                          Before you begin

                          You can download the latest version of the deployment package from my.protegrity.com. Navigate to Data Protection > Application Protector to download the latest version.

                          Upgrade the JDBC Protector based on your installation method:

                          1. Unzip the deployment package ApplicationProtector_<BUILD>_<RELEASE_VERSION>.zip.

                          2. Close or stop the application using the JDBC Protector.

                          3. Upgrade the security policy deployment.

                            • AP Java - You must uninstall the earlier version of the Application Protector before installing the new version. For more information about installing AP Java, refer to the AP Java and PEP Server section.
                            • Cloud API on AWS - For more information about upgrading the Cloud API on AWS, refer to the Cloud API on AWS guide.
                            • Cloud API on Azure - For more information about upgrading the Cloud API on Azure, refer to the Cloud API on Azure guide.
                          4. Upgrade the JDBC driver files based on your installation method.

                            • Classpath Installation: Replace the following files in your application with the files from the deployment package:

                              • protegrity-jdbc-<version>.jar
                              • protegrity-protect-<platform>-<version>.jar
                            • Maven Installation: Deploy the new version to your Maven repository and update your application’s dependencies.

                              1. Deploy the new artifacts to Maven repository:

                                mvn deploy:deploy-file \
                                  -DgroupId=com.protegrity.jdbc \
                                  -DartifactId=iap-jdbc-maven \
                                  -Dversion=<NEW_RELEASE_VERSION> \
                                  -Dpackaging=jar \
                                  -Dfile=./iap-jdbc-maven-<NEW_RELEASE_VERSION>.jar \
                                  -DpomFile=./iap-jdbc-maven-<NEW_RELEASE_VERSION>-pom.xml \
                                  -DrepositoryId=<your-repo-id> \
                                  -Durl=<https://your.maven.repo/url>
                                
                                mvn deploy:deploy-file \
                                  -DgroupId=com.protegrity.cloud \
                                  -DartifactId=protect-<PLATFORM> \
                                  -Dversion=<NEW_RELEASE_VERSION> \
                                  -Dpackaging=jar \
                                  -Dfile=./protect-<PLATFORM>-<NEW_RELEASE_VERSION>-esa.jar \
                                  -DpomFile=./protect-<PLATFORM>-pom.xml \
                                  -Dclassifier=esa \
                                  -DrepositoryId=<your-repo-id> \
                                  -Durl=<https://your.maven.repo/url>
                                
                              2. Update your application’s pom.xml with the new version:

                                <dependency>
                                  <groupId>com.protegrity.jdbc</groupId>
                                  <artifactId>iap-jdbc-maven</artifactId>
                                  <version><NEW_RELEASE_VERSION></version>
                                </dependency>
                                
                                <dependency>
                                  <groupId>com.protegrity.cloud</groupId>
                                  <artifactId>protect-<PLATFORM></artifactId>
                                  <version><NEW_RELEASE_VERSION></version>
                                  <classifier>esa</classifier>
                                </dependency>
                                
                              3. Rebuild your application to incorporate the updated dependencies.

                          5. Restart your application.

                          1.7 - Audit Logging

                          Instructions for configuring and using audit logging in JDBC Protector

                            The handling of audit records depends on how your policy is deployed. When using AP Java, audit logs are handled according to the PEP Server configuration. When using the Cloud API, audit records are recorded to CloudWatch. When using the Cloud Protect Agent, audit records are sent to the SLF4J logger. Application logs are always sent to the SLF4J logger.

                            The audit records sent to SLF4J are written as JSON records. Protection operations are batched together when possible, and an audit record is written for each batch.

                            Audit Record Fields

                            The fields are described in the following table.

                            Field

                            Description

                            additional_info.description

                            An error description or success message

                            cnt

                            Number of values processed in the batch

                            correlationid

                            The request id or query id set by the client application

                            level

                            INFO for successful, WARNING for permission denied, ERROR for errors

                            logtype

                            Always Protection

                            origin.hostname

                            The hostname of the system that generated the log entry

                            client.ip

                            IP address of the machine where the log is generated

                            client.username

                            User who triggered an event which generated the log

                            origin.time_utc

                            UTC timestamp of the request using the timezone of Protect service deployment

                            process.id

                            Process ID of the event that generated the log

                            process.thread_id

                            Thread ID of the event that generated the log

                            protection.audit_code

                            The audit code of the protect operation. List of possible errors and corresponding audit codes: - Authorized Protect: 6

                            • Authorized Unprotect: 8
                            • Unauthorized Protect/Unprotect: 3
                            • User not found: 1
                            • Data element not found: 2

                            protection.dataelement

                            The security policy field element requested

                            protection.operation

                            Protect or unprotect operation requested

                            protection.policy_user

                            User that performed the protect or unprotect

                            protector.family

                            Protector family name for which the log was generated

                            protector.vendor

                            Protector vendor name for which the log was generated

                            protector.version

                            Product build number

                            protector.pcc_version

                            Core PCC version

                            protector.core_version

                            PEP server version

                            signature.checksum

                            Hash value of the signature key ID used to sign the log message when the log is generated

                            signature.key_id

                            Key used to sign the log message when the log is generated

                            Example Audit Records

                            The following are sample audit messages:

                            Protect Success:

                            {
                                  "additional_info": {
                                    "description": "Data protect operation was successful."
                                  },
                                  "cnt": 4000,
                                  "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                  "logtype": "Protection",
                                  "level": "INFO",
                                  "origin": {
                                    "hostname": "localhost",
                                    "time_utc": 1635363966
                                  },
                                  "protection": {
                                    "dataelement": "deAddress",
                                    "operation": "Protect",
                                    "audit_code": 6,
                                    "policy_user": "test_user"
                                  },
                                  "process": {
                                    "id": "1",
                                    "thread_id": "849348352"
                                  },
                                  "client": {},
                                  "protector": {
                                    "family": "IAP Lambda",
                                    "version": "1.0.0",
                                    "vendor": "Cloud Protect",
                                    "pcc_version": "3.3.0.5",
                                    "core_version": "1.1.0"
                                  },
                                  "signature": {
                                    "key_id": "95f5a194-b0a4-4351-a",
                                    "checksum": "B324AF7C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                  }
                                }
                            

                            User permission denied:

                            {
                                  "additional_info": {
                                    "description": "The user does not have the appropriate permissions to perform the requested operation."
                                  },
                                  "cnt": 4000,
                                  "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                  "logtype": "Protection",
                                  "level": "ERROR",
                                  "origin": {
                                    "hostname": "localhost",
                                    "time_utc": 1635363966
                                  },
                                  "protection": {
                                    "dataelement": "deAddress",
                                    "operation": "Protect",
                                    "audit_code": 3,
                                    "policy_user": "test_user"
                                  },
                                  "process": {
                                    "id": "1",
                                    "thread_id": "849348352"
                                  },
                                  "client": {},
                                  "protector": {
                                    "family": "IAP Lambda",
                                    "version": "1.0.0",
                                    "vendor": "Cloud Protect",
                                    "pcc_version": "3.3.0.5",
                                    "core_version": "1.1.0"
                                  },
                                  "signature": {
                                    "key_id": "95f5a194-b0a4-4351-a",
                                    "checksum": "A216797C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                  }
                                }
                            

                            Data element not found:

                            {
                                  "additional_info": {
                                    "description": "The data element could not be found in the policy in shared memory."
                                  },
                                  "cnt": 4000,
                                  "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                  "logtype": "Protection",
                                  "level": "ERROR",
                                  "origin": {
                                    "hostname": "localhost",
                                    "time_utc": 1635363966
                                  },
                                  "protection": {
                                    "dataelement": "deAddress",
                                    "operation": "Protect",
                                    "audit_code": 2,
                                    "policy_user": "test_user"
                                  },
                                  "process": {
                                    "id": "1",
                                    "thread_id": "849348352"
                                  },
                                  "client": {},
                                  "protector": {
                                    "family": "IAP Lambda",
                                    "version": "1.0.0",
                                    "vendor": "Cloud Protect",
                                    "pcc_version": "3.3.0.5",
                                    "core_version": "1.1.0"
                                  },
                                  "signature": {
                                    "key_id": "95f5a194-b0a4-4351-a",
                                    "checksum": "AF09217C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                  }
                                }
                            

                            1.8 - Developer Reference

                            JDBC Protector developer reference and SQL behavior.

                              The JDBC Protector driver supports the Java Service Provider mechanism and will be automatically detected by the DriverManager facility or a DataSource implementation. The class that implements java.sql.Driver is com.protegrity.jdbc.Driver. JDBC URLs should begin with jdbc:iap: in order to be recognized by the driver.

                              For example, if your current database connection URL is:

                              jdbc:mysql://localhost:3306/example
                              

                              Then to use the JDBC Protector it should be modified to:

                              jdbc:iap:mysql://localhost:3306/example
                              

                              A basic implementation of a javax.sql.DataSource connection factory is provided by com.protegrity.jdbc.PtyDataSource.

                              Connection Properties

                              The table below describes the JDBC connection properties accepted by the JDBC Protector. The optimal values are automatically applied for JDBC URLs that start with any of the following:

                              • jdbc:iap:awsathena:
                              • jdbc:iap:bigquery:
                              • jdbc:iap:db2:
                              • jdbc:iap:informix-direct:
                              • jdbc:iap:informix-sqli:
                              • jdbc:iap:mariadb:
                              • jdbc:iap:mysql:
                              • jdbc:iap:oracle:
                              • jdbc:iap:postgresql:
                              • jdbc:iap:presto:
                              • jdbc:iap:sqlserver:

                              To use a different JDBC URL, adjust the connection properties below to match your requirements:

                              Property

                              Required

                              Default value

                              Description

                              conformance

                              No

                              default

                              Controls the semantics of ISO standard SQL features that are implemented in non-standard ways in some other system. For the possible values, refer to the SQL Conformance section.

                              fun

                              No

                              standard

                              Collection of built-in functions and operators. Valid values include “standard”, “bigquery”, “mysql”, “oracle”, “postgresql” and “spatial”, and also comma-separated lists, for example “oracle,spatial”.

                              lex

                              No

                              oracle

                              Lexical policy describes how identifiers are quoted, whether they are converted to upper or lower-case, or case insensitivity. For the possible values, refer to the Lexical Policy section.

                              ptyBatchSize

                              No

                              1000

                              Number of SELECT query results to include in a single batch of protect or unprotect operations. Larger values can improve the performance of the protect or unprotect operation, but will increase the time before the first result is returned to the application.

                              ptyCatalogUri

                              No

                              Location of the Protegrity catalog for mapping table columns to data elements. If it is a local file use: file:path/to/schema.json. If it is in the Java classpath use: classpath:/schema.json. For more information, refer to the Schema Configuration section.

                              ptyDbCache

                              No

                              false

                              Improves performance by caching the database schema between queries using the same connection. Any new database objects created after the connection may not be visible.

                              ptyFunctions

                              No

                              Class name of a Java POJO with methods that should be added as SQL user-defined functions. Multiple classes should be separated by commas. For more information, refer to the User-Defined Functions section.

                              ptyPolicyUser

                              No

                              Sets the Protegrity policy username. If not provided, the database user will be used instead. The username can be changed later by executing SET POLICY_USER = '<user>'.

                              ptyProtectUri

                              No

                              Location of the Protegrity security policy. Supported schemes: rps://host:port (policy sync from upstream server), file:/path (local file), s3://bucket/key (AWS S3). If not provided, the value will be loaded from the cloud-protect.properties file in the Java classpath.

                              ptyStmtCacheSize

                              No

                              0

                              Improves performance by caching the query plan for prepared statements. Changes to the table schema will not invalidate the cache and may cause unexpected behavior. The default value of “0” disables the cache.

                              SQL Conformance

                              The JDBC Protector can be configured to accept or reject certain SQL features and extensions based on the value of the conformance property used when creating the connection. The table below lists the possible values for this property.

                              NameDescription
                              DEFAULTEnables compatibility with the most common SQL dialects
                              BABELEnables compatibility with all SQL dialects
                              LENIENTSimilar to BABEL without support for some types of JOIN clauses
                              STRICT_92Restricts to the SQL:92 standard
                              STRICT_99Restricts to the SQL:99 standard
                              PRAGMATIC_99Enables SQL semantics consistent with SQL:99 and some common extensions
                              STRICT_2003Restricts to the SQL:2003 standard
                              PRAGMATIC_2003Enables SQL semantics consistent with SQL:2003 and some common extensions
                              BIG_QUERYEnables SQL semantics consistent with BigQuery
                              MYSQL_5Enables SQL semantics consistent with MySQL 5.x
                              ORACLE_10Enables SQL semantics consistent with Oracle 10
                              ORACLE_12Enables SQL semantics consistent with Oracle 12
                              PRESTOEnables SQL semantics consistent with Presto
                              SQL_SERVER_2008Enables SQL semantics consistent with SQL Server 2008

                              Lexical Policy

                              The lexical policy defines the character used for quoting identifiers and whether to enable case-sensitive matching of identifiers. The value of the lex property used when creating the connection defines which lexical policy will be used. The table below lists the possible values for this property.

                              NameDescription
                              BIG_QUERYCompatible with BigQuery. Identifiers are not case-sensitive and can be quoted with back-ticks. A back-tick is escaped by using a backslash. Character literals may be enclosed in single or double quotes.
                              JAVAIdentifiers are case-sensitive and can be quoted with back-ticks. A back-tick is escaped by using another back-tick.
                              MYSQLCompatible with MySQL for Windows without ANSI_QUOTES. Identifiers are not case-sensitive and can be quoted with back-ticks. A back-tick is escaped by using another back-tick.
                              MYSQL_ANSICompatible with MySQL for Windows when ANSI_QUOTES is enabled. Identifiers are not case-sensitive and can be quoted with quotation marks.
                              ORACLECompatible with Oracle. Identifiers are case-sensitive and can be quoted with quotation marks. Unquoted identifiers are converted to upper-case.
                              SQL_SERVERCompatible with Microsoft SQL Server. Identifiers are not case-sensitive and can be quoted with brackets.

                              SQL Grammar

                              This section describes the SQL dialect recognized by the JDBC Protector’s default SQL parser. The default grammar is SQL 2003 standard with some extensions from Oracle, MySQL, PostgreSQL, and SQL Server.

                              CALL

                              
                              CALL identifier '(' [ param [ , param ]* ] ')'
                              

                              COMMIT

                              
                              COMMIT [ WORK ] [ AND { CHAIN | NO CHAIN ] ]
                              

                              DELETE

                              
                              DELETE FROM [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                              [ WHERE booleanExpression ]
                              

                              INSERT/UPSERT

                              
                              { INSERT | UPSERT } INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                              [ '(' column [, column ]* ')' ]
                              { [values](jdbc_dev_calcite_ref_statementSelectValues.md) | [query](jdbc_dev_calcite_ref_statementSelect.md) }
                              [ ON CONFLICT DO
                                  {
                                      NOTHING
                                  |   UPDATE SET identifier '=' expression [, identifier '=' expression ]*
                                  }
                              ]
                              

                              MERGE

                              
                              MERGE INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                              USING [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                              ON booleanExpression
                              [ WHEN MATCHED THEN UPDATE SET identifier '=' expression [, identifier '=' expression ]* ]
                              [ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
                              

                              RESET

                              
                              [ ALTER { SYSTEM | SESSION } ] RESET { identifier | ALL }
                              

                              ROLLBACK

                              
                              ROLLBACK [ WORK ] [ AND { CHAIN | NO CHAIN ] ] [ TO SAVEPOINT identifier ]
                              

                              SAVEPOINT

                              
                              [ RELEASE ] SAVEPOINT identifier
                              

                              SELECT

                              [WITH [ RECURSIVE ] withItem [ , withItem ]* query]
                              SELECT [ hintComment ] [ STREAM ]
                              [ SKIP UnsignedNumericLiteralOrParam ]
                              [
                                { FIRST | LIMIT } UnsignedNumericLiteralOrParam
                                | TOP { '(' UnsignedNumericLiteralOrParam ')' | UnsignedNumericLiteralOrParam }
                              ]
                              [ ALL | DISTINCT ]
                              { * | projectItem [, projectItem ]* }
                              [ FROM tableExpression ]
                              [ WHERE booleanExpression ]
                              [ GROUP BY [ ALL | DISTINCT ] { groupItem [, groupItem ]* } ]
                              [ HAVING booleanExpression ]
                              [ WINDOW windowName AS windowSpec [, windowName AS windowSpec ]* ]
                              [ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] query ]
                              [ QUALIFY booleanExpression ]
                              [ ORDER BY orderItem [, orderItem ]* ]
                              [ LIMIT [ start, ] { count | ALL } ]
                              [ OFFSET start { ROW | ROWS } ]
                              [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
                              [ FOR { SHARE | UPDATE } [ { NOWAIT | SKIP LOCKED } ] ]
                              

                              groupItem

                              
                                  expression
                              |   '(' ')'
                              |   '(' expression [, expression ]* ')'
                              |   CUBE '(' expression [, expression ]* ')'
                              |   ROLLUP '(' expression [, expression ]* ')'
                              |   GROUPING SETS '(' groupItem [, groupItem ]* ')'
                              

                              hintComment

                              
                              hintComment:
                                      '/*+' { hintName | hintName '(' hintOptions ')' } '*/'
                              
                              
                              hintOptions:
                                      hintKVOption [, hintKVOption ]*
                                  |   optionName [, optionName ]*
                                  |   hintOptionValue [, hintOptionValue ]*
                              
                              hintKVOption:
                                      optionName '=' stringLiteral
                                  |   stringLiteral '=' stringLiteral
                              
                              hintOptionValue:
                                      stringLiteral | numericLiteral
                              

                              matchRecognize

                              JDBC Protector uses Apache Calcite for SQL statement parsing. MATCH_RECOGNIZE is a SQL extension for recognizing sequences of events in complex event processing (CEP). It is experimental in Apache Calcite, and may not be fully implemented yet.

                              
                              matchRecognize:
                                      MATCH_RECOGNIZE
                                      '('
                                      [ PARTITION BY expression [, expression ]* ]
                                      [ ORDER BY order ]
                                      [ MEASURES expression AS alias [, expression AS alias ]* ]
                                      [ ONE ROW PER MATCH | ALL ROWS PER MATCH ]
                                      [ AFTER MATCH skip ]
                                      PATTERN '(' [ '^' ] pattern [ '$' ] ')'
                                      [ WITHIN  intervalLiteral ]
                                      [ SUBSET  subsetItem [, subsetItem ]* ]
                                      DEFINE  variable AS condition [, variable AS condition ]*
                                      ')'
                              
                              order:
                                      ORDER OF tableIdentifier
                                  |   [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) [, [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) ]*
                              
                              skip:
                                      SKIP TO NEXT ROW
                                  |   SKIP PAST LAST ROW
                                  |   SKIP TO FIRST identifier
                                  |   SKIP TO [ LAST ] identifier
                              
                              pattern:
                                      patternTerm [ '|' patternTerm ]*
                              
                              patternTerm:
                                      patternFactor [ patternFactor ]*
                              
                              patternFactor:
                                      patternPrimary [ patternQuantifier ]
                              
                              patternPrimary:
                                      identifier
                                  | 	'(' pattern ')'
                                  | 	'{-' pattern '-}'
                                  | 	PERMUTE '(' pattern [ , pattern ]* ')'
                              
                              patternQuantifier:
                                      '*'
                                  |   '+'
                                  |   '{' minRepeatNumericLiteral [ , maxRepeatNumericLiteral ] '}'
                                  |   '{' repeatNumericLiteral '}'
                                  |   '{-' pattern '-}'
                              
                              
                              intervalLiteral:
                                      INTERVAL [ '-' | '+' ] stringLiteral timeUnit [ TO timeUnit ]
                              
                              subsetItem:
                                      identifier '=(' expression [ , expression ]* ')'
                              

                              orderItem

                              
                              expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
                              

                              pivot

                              
                              pivot:
                                      PIVOT '('
                                      pivotAgg [, pivotAgg ]*
                                      FOR { column |  '(' column [, column ]* ')'
                                      IN '(' pivotExpression [, pivotExpression ]* ')'
                                      ')'
                              
                              pivotAgg:
                                      agg '(' [ ALL | DISTINCT ] value [, value ]* ')'
                                      [ [ AS ] alias ]
                              
                              pivotExpression:
                                      { expression |  '(' expression [, expression ]* ')' } [ [ AS ] alias ]
                              

                              projectItem

                              
                              expression [ [ AS ] columnAlias ] | tableAlias . *
                              

                              tableExpression

                              
                              tableExpression:
                                      tableReference [, tableReference ]*
                                  |   tableExpression
                                      [ NATURAL ] [ { LEFT | RIGHT | FULL } [ OUTER ] ]
                                      JOIN tableExpression
                                      [ joinCondition ]
                                  |   tableExpression CROSS JOIN tableExpression
                                  |   tableExpression [ CROSS | OUTER ] APPLY tableExpression
                              
                              tableReference:
                                      tablePrimary
                                      [ FOR SYSTEM_TIME AS OF expression ]
                                      [ [pivot](jdbc_dev_calcite_ref_statementSelectPivot.md) ]
                                      [ [unpivot](jdbc_dev_calcite_ref_statementSelectUnpivot.md) ]
                                      [ [matchRecognize](jdbc_dev_calcite_ref_statementSelectMatchRecognize.md) ]
                                      [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
                              
                              tablePrimary:
                                      [ [ catalogName . ] schemaName . ] tableName
                                      '(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
                                  |   tablePrimary [ [hintComment](jdbc_dev_calcite_ref_statementSelectHintComment.md) ] [ EXTEND ] columnDeclarations
                                  |   [ LATERAL ] '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                                  |   UNNEST '(' expression ')' [ WITH ORDINALITY ]
                                  |   [ LATERAL ] TABLE
                                      '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
                              
                              joinCondition:
                                      ON booleanExpression
                                  |   USING '(' column [, column ]* ')'
                              
                              columnDeclarations:
                                      '(' column type [ NOT NULL ] [, column type [ NOT NULL ] ]* ')'
                              

                              unpivot

                              
                              unpivot:
                                      UNPIVOT [ INCLUDING NULLS | EXCLUDING NULLS ] '('
                                      { column | '(' column [, column ]* ')' }
                                      FOR { column | '(' column [, column ]* ')' }
                                      IN '(' unpivotValue [, unpivotValue ]* ')'
                                      ')'
                              
                              unpivotValue:
                                      column [ AS literal ]
                                  |   '(' column [, column ]* ')' [ AS '(' literal [, literal ]* ')' ]
                              

                              values

                              
                              values:
                                      { VALUES | VALUE } rowConstructor [, rowConstructor ]*
                              
                              rowConstructor:
                                      { '(' ROW rowSpec ')' | ROW } rowSpec | expression
                              
                              rowSpec:
                                      '(' { { values | [query](jdbc_dev_calcite_ref_statementSelect.md) } | DEFAULT } [ , { expression | DEFAULT } ]* ')'
                              

                              windowSpec

                              
                              '('
                              [ windowName ]
                              [ ORDER BY orderItem [, orderItem ]* ]
                              [ PARTITION BY expression [, expression ]* ]
                              [
                                  RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
                              |   ROWS numericExpression { PRECEDING | FOLLOWING }
                              ]
                              ')'
                              

                              withItem

                              
                              name
                              [ '(' column [, column ]* ')' ]
                              AS '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                              

                              SET

                              [ ALTER { SYSTEM | SESSION } ] SET identifier { TO | '=' } { literal | identifier | ON }
                              

                              SET CONSTRAINTS

                              
                              SET CONSTRAINTS { ALL | identifier [ , identifier ] } { DEFERRED | IMMEDIATE }
                              

                              SET TRANSACTION

                              
                              SET [ LOCAL ] TRANSACTION [transactionCharacteristics](jdbc_dev_calcite_ref_statementTransactionCharacteristics.md)
                              

                              START TRANSACTION

                              START TRANSACTION transactionCharacteristics
                              

                              transactionCharacteristics

                              transactionCharacteristics:
                              [ transactionMode [ , transactionMode ]* ]
                              
                              transactionMode:
                              ISOLATION LEVEL transactionLevel
                              | { READ WRITE | READ ONLY }
                              | DIAGNOSTICS SIZE UnsignedIntLiteral
                              
                              transactionLevel:
                              READ COMMITTED
                              | READ UNCOMMITTED
                              | REPEATABLE READ
                              | SERIALIZABLE
                              

                              UPDATE

                              
                              UPDATE [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                              SET identifier '=' expression [, identifier '=' expression ]*
                              [ WHERE booleanExpression ]
                              

                              Tokenization Types

                              This section describes how to use each of the Protegrity tokenization types with the JDBC Protector and supplements the Protegrity Protection Methods Reference Guide.

                              The following tokenization types are not currently supported:

                              • Unicode
                              • Binary

                              Numeric (0-9)

                              The Numeric token type tokenizes digits from 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Numeric token.
                              Input ValueTokenized ValueComments
                              -7634.119-4306.861Decimal point and sign are treated as delimiters and not tokenized.
                              12+38=5098+24=62Arithmetic signs are treated as delimiters and not tokenized.
                              704-BBJ134-BBJAlpha characters are treated as delimiters and not tokenized.

                              Integer (0-9)

                              The Integer token type tokenizes 2, 4, or 8 byte sized integers.

                              Tokenization Type Properties

                              Settings

                              Name

                              Integer

                              Token Type and Format

                              2, 4, or 8 byte sized integers

                              Supported input data types

                              All Databases

                              INTEGER

                              The following table shows examples of the way in which a value will be tokenized with the Integer token.
                              Input ValueTokenized ValueComments
                              31465For 2 bytes, the values can range from -32768 to 32767.
                              3782939681For 4 bytes, the values can range from -2147483648 to 2147483647.
                              37268379031142372719For 8 bytes, the value range can range from -9223372036854775808 to 9223372036854775807.

                              Credit Card

                              The Credit Card token type helps maintain transparency, and also provides a way to clearly distinguish a token from the real value, which is a recommendation of the PCI DSS.

                              Tokenization Type Properties

                              Settings

                              Name

                              Credit Card

                              Token Type and Format

                              Digits 0 through 9

                              (no separators are allowed as input)

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              Alpha (A-Z)

                              The Alpha token type tokenizes both uppercase and lowercase letters.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha

                              Token Type and Format

                              Lowercase letters ‘a’ through ‘z’

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Alpha token.
                              Input ValueTokenized ValueComments
                              131 Summer Street, Bridgewater131 VDYgAK qvMDUn, zAEXmwqWYNQGNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                              Albert EinsteinSldGzm OOCTzSFoSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                              Upper-case Alpha (A-Z)

                              The Upper-case Alpha token type tokenizes all alphabetic symbols as uppercase. After de-tokenization, all alphabetic symbols are returned as uppercase. This means that initial and detokenized values would not match if the input contains lowercase letters.

                              Tokenization Type Properties

                              Settings

                              Name

                              Upper-case Alpha

                              Token Type and Format

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Upper-case Alpha token.
                              Input ValueTokenized ValueComments
                              abcOIMLowercase characters in the input are converted to uppercase in output. De-tokenization will return ‘ABC’.
                              131 Summer Street, Bridgewater131 ZBXDPW GFYTZP, CRTTPXPLYGCUNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                              Albert EinsteinAOALXO POHLFHMUSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                              Alpha-Numeric (0-9, a-z, A-Z)

                              The Alpha-Numeric token type tokenizes all alphabetic symbols (both lowercase and uppercase letters), as well as digits from 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha-Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Lowercase letters ‘a’ through ‘z’

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Alpha-Numeric token.
                              Input ValueTokenized ValueComments
                              123sQOInput is numeric but tokenized value contains uppercase and lowercase alpha characters.
                              131 Summer Street, BridgewaterikC ejCxxp kLa2ZZ, 5x8K2IMubcnSpaces and comma are treated as delimiters and not tokenized.
                              704-BBJjf7-oVYDash is treated as delimiter. The rest of value is tokenized.

                              Upper Alpha-Numeric (0-9, A-Z)

                              The Upper Alpha-Numeric token type tokenizes uppercase letters A through Z and digits 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Upper Alpha-Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Upper Alpha-Numeric token.
                              Input ValueTokenized ValueComments
                              123STDInput is numeric but tokenized value contains uppercase alpha characters.
                              131 Summer Street, Bridgewater8C9 CSD5PS 1X5ZJH, 231JHXW8CVFSpaces and comma are treated as delimiters and not tokenized. Lowercase characters in the input are converted to uppercase in output. De-tokenization will return all alpha characters in upper case.

                              Lower ASCII

                              The Lower ASCII token type is provided to address the handling of spaces in such data types as CHAR and VARCHAR.

                              Tokenization Type Properties

                              Settings

                              Name

                              Lower ASCII

                              Token Type and Format

                              The lower part of the ASCII table:

                              Hex character codes from 0x21 to 0x7E

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Lower ASCII token.

                              Input Value

                              Tokenized Value

                              Comments

                              La Scala 05698

                              :H HnwqP v/Q`>

                              All characters in the input value (except of spaces) are tokenized.

                              Ford Mondeo CA-0256TY

                              M34 567 K-45

                              j`1$ nRSD<X T]!(~4MWF

                              l:f cF+ R?V{

                              All characters in the input value (except of spaces) are tokenized.

                              **

                              Printable

                              The Printable token type tokenizes ASCII printable characters from the ISO 8859-15 alphabet, which include letters, digits, punctuation marks, and miscellaneous symbols.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha

                              Token Type and Format

                              ASCII printable characters, which include letters, digits, punctuation marks, and miscellaneous symbols

                              Hex character codes from 0x20 to 0x7E and from 0xA0 to 0xFF

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Printable token.

                              Input Value

                              Tokenized Value

                              Comments

                              La Scala 05698

                              F|ZpÙç|Ôä%s^¦4

                              All characters in the input value (including spaces) are tokenized.

                              Ford Mondeo CA-0256TY

                              M34 567 K-45

                              §)%ß#)ðYjt{¬ÓÊEµV²ù²

                              All characters in the input value (including spaces) are tokenized.

                              Date (YYYY-MM-DD, DD/MM/YYYY, MM.DD.YYYY)

                              The Date token type protects dates in big endian, little endian, or middle endian form.

                              The following formats are supported:

                              • YYYY<delim>MM<delim>DD
                              • DD<delim>MM<delim>YYYY
                              • MM<delim>DD<delim>YYYY

                              where <delim> is one of the allowed separators: . (dot), / (slash), or - (dash).

                              Tokenization Type Properties

                              Settings

                              Name

                              Date

                              Token Type and Format

                              Date in big endian form, starting with the year (YYYY-MM-DD)

                              Date in little endian form, starting with the day (DD/MM/YYYY)

                              Date in middle endian form, starting with the month (MM.DD.YYYY)

                              The following separators are supported: . (dot), / (slash), - (dash)

                              Supported input data types *1

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              Supported range of input dates

                              From “0600-01-01” to “3337-11-27”

                              Date token types are not fully validated for input value as valid date. For example, a day value greater than 31 and month value greater than 12 results in an error, but the date input 2011-02-30 does not. However, the detokenized value would be 2011-03-02, which is not the initial value.

                              The following table shows examples of the way in which a value will be tokenized with the Date token.

                              Input Value

                              Tokenized Value

                              Comments

                              2012-02-29

                              2012/02/29

                              2012.02.29

                              2150-02-20

                              2150/02/20

                              2150.02.20

                              All three separators are successfully accepted. They are treated as delimiters not impacting tokenized value.

                              31/01/0600

                              08/05/2215

                              Date in the past is tokenized.

                              10.30.3337

                              09.05.2042

                              Date in the future is tokenized.

                              • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                                The following points are applicable for the tokenization and de-tokenization of the cutover dates of the Proleptic Gregorian Calendar:

                                • The tokenization of the date values in the cutover date range of the Proleptic Gregorian Calendar results in an ‘Invalid Input’ error.
                                • During tokenization, an internal validation is performed to check whether the value is tokenized to the cutover date. If it is a cutover date, then the Year part (1582) of the tokenized value is converted to 3338 and then returned. During de-tokenization, an internal check is performed to validate whether the Year is 3338. If the Year is 3338, then it is internally converted to 1582.

                              Datetime (YYYY-MM-DD HH:MM:SS)

                              The Datetime token type was introduced in response to requirements to allow specific date parts to remain in the clear and for date tokens to be distinguishable from real dates. This token type will also allow for time to be tokenized (HH:MM:SS) with the exception of milliseconds (MMM).

                              Tokenization Type Properties

                              Settings

                              Name

                              Datetime

                              Token Type and Format

                              Datetime in the following formats:

                              YYYY-MM-DD HH:MM:SS.MMM

                              YYYY-MM-DDTHH:MM:SS.MMM

                              YYYY-MM-DD HH:MM:SS

                              YYYY-MM-DDTHH:MM:SS

                              YYYY-MM-DD

                              From “0600-01-01” to “3337-11-27”, alphabetic digits 0-9, only specific delimiters

                              Input separators (delimiter) between date, month and year

                              . (dot), / (slash), or - (dash)

                              Input separators (delimiter) between hours, minutes and seconds

                              : (colon) only

                              Input separator (delimiter) between date and hour

                              " " (space) or “T” (the letter T)

                              Input separator (delimiter) between seconds and milliseconds

                              . (dot) or , (comma)

                              Supported input data types *1 *2

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Datetime token.

                              Input ValueTokenized ValueComments
                              2009.04.12 12:23:34.3331595.06.19 14:31:51.333YYYY-MM-DD HH:MM:SS.MMM. Milliseconds value is left in the clear.
                              2009.04.12 12:23:341595.06.19 14:31:51YYYY-MM-DD HH:MM:SS with space separator between day and hour.
                              2234.10.12T12:23:232755.08.04T22:33:43YYYY-MM-DDTHH:MM:SS with T separator between day and hour values.
                              • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                              Decimal

                              The Decimal token type tokenizes numbers which may have a precision and scale. The resulting token does not contain any zeros which makes it suitable to store in a decimal data type in a database. Any sign or decimal point delimiter are stripped from the input value before tokenization and put back after tokenization.

                              Tokenization Type Properties

                              Settings

                              Name

                              Decimal

                              Token Type and Format

                              Digits 0 through 9 in input value, 1 thorough 9 in output value

                              The sign (+ or -) and decimal point (. or ,) separator

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Decimal token.
                              Input ValueTokenized ValueComments
                              519.02268.68Input value has (.) dot separator.
                              -0.333807-9.893967Input value has sign and (.) dot separator.
                              +,461+,918Input value has sign and (,) comma separator.

                              Email

                              Email token type allows tokenization of an email address. Email token keeps the domain name along with all characters after the “@” sign, and the “@” sign itself in the clear. The local part (i.e. the part before “@”) gets tokenized.

                              Tokenization Type Properties

                              Settings

                              Name

                              Email

                              Token Type and Format

                              Alphabetic and numeric only. The rest characters will be treated as delimiters.

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              No Encryption

                              The No Encryption protection method when applied lets sensitive data be stored in the clear, but either monitors or masks its usage through a data security policy. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                              Protection Method

                              Database

                              Oracle

                              Other Database

                              No Encryption

                              CHAR

                              INTEGER

                              VARCHAR2

                              CHAR

                              INTEGER

                              VARCHAR

                              Encryption Algorithms

                              Encryption is the conversion of data into a ciphertext using an algorithmic scheme. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                              Encryption Algorithm

                              All Databases

                              3DES

                              AES-128

                              AES-256

                              CUSP 3DES

                              CUSP AES-128

                              CUPS AES-256

                              VARBINARY

                              DTP2-AES-128

                              DTP2-AES-256

                              DTP2-3DES

                              DTP2-SHA1

                              Not supported

                              Hashing

                              The JDBC Protector does not currently support the Protegrity hashing protection methods.

                              Masking

                              For situations where data output restrictions must be applied for users, the Masking method can be used. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                              Protection Method

                              Database

                              Oracle

                              Other Database

                              Masking

                              CHAR

                              INTEGER

                              VARCHAR2

                              CHAR

                              INTEGER

                              VARCHAR

                              Data Types

                              This section describes the data types that you can use with the JDBC Protector.

                              Standard Data Types Reference

                              The JDBC Protector leverages Apache Calcite for supporting the standard SQL data types. For more information and a list of available data types, refer to the Apache Calcite SQL Language reference guide.

                              Conversion Between Java and JDBC Types

                              The Protegrity JDBC Protector is flexible in the way it handles conversions between JDBC types and Java types. Any JDBC type can be converted to a String. Calling the ResultSet.getObject() method will return the Java object provided by the database driver. The following table shows the possible ResultSet conversions for each SQL type.

                              JDBC Types

                              Java Types

                              BIGINT

                              DECIMAL

                              DOUBLE

                              FLOAT

                              INTEGER

                              NUMERIC

                              REAL

                              SMALLINT

                              TINYINT

                              double

                              boolean

                              byte

                              float

                              int

                              long

                              short

                              String

                              java.math.BigDecimal

                              BINARY

                              CHAR

                              VARBINARY

                              VARCHAR

                              byte[]

                              String

                              DATE

                              int

                              long

                              String

                              java.sql.Date

                              TIME

                              int

                              long

                              String

                              java.sql.Time

                              TIMESTAMP

                              long

                              String

                              java.sql.Date

                              java.sql.Time

                              java.sql.Timestamp

                              ARRAY

                              java.sql.Array

                              STRUCT

                              java.sql.Struct

                              Functions and Operators

                              This section describes the SQL functions and operators that you can use with the JDBC Protector. Additionally, refer to the documentation for your database provider. Functions and operators must be supported by both the JDBC Protector and your database provider to use them in your SQL statements.

                              Standard Functions and Operators Reference

                              The JDBC Protector leverages Apache Calcite to provide common functions and operators for use in your SQL statements. For more information and a list of available functions and operators, refer to the Apache Calcite SQL Language reference guide.

                              The following SQL functions are provided in addition to those provided by Apache Calcite:

                              Database ProviderFunctionNotes
                              PostgreSQLage(timestamp, timestamp)Requires a ‘FROM’ clause and does not support protected columns. Example: SELECT age(CURRENT_DATE, DATE ‘2023-01-01’) FROM ’table-name’.
                              PostgreSQLdate_add( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_add(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                              PostgreSQLdate_subtract( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_subtract(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                              PostgreSQLclock_timestamp()When used with a protected column, the timezone will be stripped and may throw an exception.
                              PostgreSQLcurrval( char )
                              PostgreSQLlastval()
                              PostgreSQLnextval( char )
                              PostgreSQLsetval( char, bigint [, boolean] )
                              PostgreSQLto_number( char, char )When used with a protected column, the timezone will be stripped and may throw an exception.
                              PostgreSQLxml( char )Throws an exception when used with a protected column.
                              PostgreSQLxmltable(...)For additional info see PostgreSQL XMLTABLE function documentation. Known Limitations: 1) XMLTABLE does not support PASSING clause with a sub-query, e.g. ‘PASSING (SELECT col-name FROM table-name)’ 2) XMLTABLE does not support TEXT data type, use VARCHAR(n) instead, e.g. instead of ‘COLUMNS col-name TEXT’ use ‘COLUMNS col-name VARCHAR(100)’

                              Protegrity Functions

                              The JDBC Protector provides SQL functions for controlling when the data protection operations occur. This can be used in combination with other SQL functions to, for example, encode protected data before it is stored in the database. When the JDBC Protector encounters one of the functions below in a SQL query, it runs the input expression locally and applies the data protection operation to the result.

                              pty_protect

                              Protects values using the given data element.

                              PTY_PROTECT(dataElement, values)

                              • Parameters

                                NameTypeDescription
                                dataElementVARCHARName of the data element.
                                valuesAnyData to protect. For more information on supported data types, see Tokenization Types.
                              • Returns

                                Protected values.

                              • Exception

                                If the user does not have protect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                              • Example

                                select pty_protect('deTokName', column) from table
                                
                                select "pty_protect"('deTokName', column) from table
                                

                              pty_unprotect

                              Unprotects values using the given data element.

                              PTY_UNPROTECT(dataElement, values)

                              • Parameters

                                NameTypeDescription
                                dataElementVARCHARName of the data element.
                                valuesAnyData to unprotect. For more information on supported data types, see Tokenization Types.
                              • Returns

                                Unprotected value.

                              • Exception

                                If the user does not have unprotect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                              • Example

                                select pty_unprotect('deTokName', column) from table
                                
                                select "pty_unprotect"('deTokName', column) from table
                                

                              User-Defined Functions

                              A user-defined function (UDF) is a SQL function that invokes a Java class to transform data. It can be used in combination with Protegrity Functions to modify how the data protection is applied.

                              A list of Java class names providing UDFs can be provided as the ptyFunctions property when opening a JDBC connection. The Java classes should be POJOs with one or more public static methods. These methods will be made available as a SQL function with the same name as the method.

                              The example below executes a SQL function using a UDF defined in the MyPlusFunction class. If this class is added to the com.example package, then the ptyFunctions connection property should be set to com.example.MyPlusFunction.

                              public class MyPlusFunction {
                                  public static void int MY_PLUS(int left, int right) {
                                      return left + right;
                                  }
                              }
                              
                              SELECT MY_PLUS(1, 2)
                              

                              For more information about which Java types are used for each SQL type, refer to the Conversion Between Java and JDBC Types section.

                              1.8.1 -

                              Tokenization Types

                              This section describes how to use each of the Protegrity tokenization types with the JDBC Protector and supplements the Protegrity Protection Methods Reference Guide.

                              The following tokenization types are not currently supported:

                              • Unicode
                              • Binary

                              Numeric (0-9)

                              The Numeric token type tokenizes digits from 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Numeric token.
                              Input ValueTokenized ValueComments
                              -7634.119-4306.861Decimal point and sign are treated as delimiters and not tokenized.
                              12+38=5098+24=62Arithmetic signs are treated as delimiters and not tokenized.
                              704-BBJ134-BBJAlpha characters are treated as delimiters and not tokenized.

                              Integer (0-9)

                              The Integer token type tokenizes 2, 4, or 8 byte sized integers.

                              Tokenization Type Properties

                              Settings

                              Name

                              Integer

                              Token Type and Format

                              2, 4, or 8 byte sized integers

                              Supported input data types

                              All Databases

                              INTEGER

                              The following table shows examples of the way in which a value will be tokenized with the Integer token.
                              Input ValueTokenized ValueComments
                              31465For 2 bytes, the values can range from -32768 to 32767.
                              3782939681For 4 bytes, the values can range from -2147483648 to 2147483647.
                              37268379031142372719For 8 bytes, the value range can range from -9223372036854775808 to 9223372036854775807.

                              Credit Card

                              The Credit Card token type helps maintain transparency, and also provides a way to clearly distinguish a token from the real value, which is a recommendation of the PCI DSS.

                              Tokenization Type Properties

                              Settings

                              Name

                              Credit Card

                              Token Type and Format

                              Digits 0 through 9

                              (no separators are allowed as input)

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              Alpha (A-Z)

                              The Alpha token type tokenizes both uppercase and lowercase letters.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha

                              Token Type and Format

                              Lowercase letters ‘a’ through ‘z’

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Alpha token.
                              Input ValueTokenized ValueComments
                              131 Summer Street, Bridgewater131 VDYgAK qvMDUn, zAEXmwqWYNQGNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                              Albert EinsteinSldGzm OOCTzSFoSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                              Upper-case Alpha (A-Z)

                              The Upper-case Alpha token type tokenizes all alphabetic symbols as uppercase. After de-tokenization, all alphabetic symbols are returned as uppercase. This means that initial and detokenized values would not match if the input contains lowercase letters.

                              Tokenization Type Properties

                              Settings

                              Name

                              Upper-case Alpha

                              Token Type and Format

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Upper-case Alpha token.
                              Input ValueTokenized ValueComments
                              abcOIMLowercase characters in the input are converted to uppercase in output. De-tokenization will return ‘ABC’.
                              131 Summer Street, Bridgewater131 ZBXDPW GFYTZP, CRTTPXPLYGCUNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                              Albert EinsteinAOALXO POHLFHMUSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                              Alpha-Numeric (0-9, a-z, A-Z)

                              The Alpha-Numeric token type tokenizes all alphabetic symbols (both lowercase and uppercase letters), as well as digits from 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha-Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Lowercase letters ‘a’ through ‘z’

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Alpha-Numeric token.
                              Input ValueTokenized ValueComments
                              123sQOInput is numeric but tokenized value contains uppercase and lowercase alpha characters.
                              131 Summer Street, BridgewaterikC ejCxxp kLa2ZZ, 5x8K2IMubcnSpaces and comma are treated as delimiters and not tokenized.
                              704-BBJjf7-oVYDash is treated as delimiter. The rest of value is tokenized.

                              Upper Alpha-Numeric (0-9, A-Z)

                              The Upper Alpha-Numeric token type tokenizes uppercase letters A through Z and digits 0 to 9.

                              Tokenization Type Properties

                              Settings

                              Name

                              Upper Alpha-Numeric

                              Token Type and Format

                              Digits 0 through 9

                              Uppercase letters ‘A’ through ‘Z’

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Upper Alpha-Numeric token.
                              Input ValueTokenized ValueComments
                              123STDInput is numeric but tokenized value contains uppercase alpha characters.
                              131 Summer Street, Bridgewater8C9 CSD5PS 1X5ZJH, 231JHXW8CVFSpaces and comma are treated as delimiters and not tokenized. Lowercase characters in the input are converted to uppercase in output. De-tokenization will return all alpha characters in upper case.

                              Lower ASCII

                              The Lower ASCII token type is provided to address the handling of spaces in such data types as CHAR and VARCHAR.

                              Tokenization Type Properties

                              Settings

                              Name

                              Lower ASCII

                              Token Type and Format

                              The lower part of the ASCII table:

                              Hex character codes from 0x21 to 0x7E

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Lower ASCII token.

                              Input Value

                              Tokenized Value

                              Comments

                              La Scala 05698

                              :H HnwqP v/Q`>

                              All characters in the input value (except of spaces) are tokenized.

                              Ford Mondeo CA-0256TY

                              M34 567 K-45

                              j`1$ nRSD<X T]!(~4MWF

                              l:f cF+ R?V{

                              All characters in the input value (except of spaces) are tokenized.

                              **

                              Printable

                              The Printable token type tokenizes ASCII printable characters from the ISO 8859-15 alphabet, which include letters, digits, punctuation marks, and miscellaneous symbols.

                              Tokenization Type Properties

                              Settings

                              Name

                              Alpha

                              Token Type and Format

                              ASCII printable characters, which include letters, digits, punctuation marks, and miscellaneous symbols

                              Hex character codes from 0x20 to 0x7E and from 0xA0 to 0xFF

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Printable token.

                              Input Value

                              Tokenized Value

                              Comments

                              La Scala 05698

                              F|ZpÙç|Ôä%s^¦4

                              All characters in the input value (including spaces) are tokenized.

                              Ford Mondeo CA-0256TY

                              M34 567 K-45

                              §)%ß#)ðYjt{¬ÓÊEµV²ù²

                              All characters in the input value (including spaces) are tokenized.

                              Date (YYYY-MM-DD, DD/MM/YYYY, MM.DD.YYYY)

                              The Date token type protects dates in big endian, little endian, or middle endian form.

                              The following formats are supported:

                              • YYYY<delim>MM<delim>DD
                              • DD<delim>MM<delim>YYYY
                              • MM<delim>DD<delim>YYYY

                              where <delim> is one of the allowed separators: . (dot), / (slash), or - (dash).

                              Tokenization Type Properties

                              Settings

                              Name

                              Date

                              Token Type and Format

                              Date in big endian form, starting with the year (YYYY-MM-DD)

                              Date in little endian form, starting with the day (DD/MM/YYYY)

                              Date in middle endian form, starting with the month (MM.DD.YYYY)

                              The following separators are supported: . (dot), / (slash), - (dash)

                              Supported input data types *1

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              Supported range of input dates

                              From “0600-01-01” to “3337-11-27”

                              Date token types are not fully validated for input value as valid date. For example, a day value greater than 31 and month value greater than 12 results in an error, but the date input 2011-02-30 does not. However, the detokenized value would be 2011-03-02, which is not the initial value.

                              The following table shows examples of the way in which a value will be tokenized with the Date token.

                              Input Value

                              Tokenized Value

                              Comments

                              2012-02-29

                              2012/02/29

                              2012.02.29

                              2150-02-20

                              2150/02/20

                              2150.02.20

                              All three separators are successfully accepted. They are treated as delimiters not impacting tokenized value.

                              31/01/0600

                              08/05/2215

                              Date in the past is tokenized.

                              10.30.3337

                              09.05.2042

                              Date in the future is tokenized.

                              • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                                The following points are applicable for the tokenization and de-tokenization of the cutover dates of the Proleptic Gregorian Calendar:

                                • The tokenization of the date values in the cutover date range of the Proleptic Gregorian Calendar results in an ‘Invalid Input’ error.
                                • During tokenization, an internal validation is performed to check whether the value is tokenized to the cutover date. If it is a cutover date, then the Year part (1582) of the tokenized value is converted to 3338 and then returned. During de-tokenization, an internal check is performed to validate whether the Year is 3338. If the Year is 3338, then it is internally converted to 1582.

                              Datetime (YYYY-MM-DD HH:MM:SS)

                              The Datetime token type was introduced in response to requirements to allow specific date parts to remain in the clear and for date tokens to be distinguishable from real dates. This token type will also allow for time to be tokenized (HH:MM:SS) with the exception of milliseconds (MMM).

                              Tokenization Type Properties

                              Settings

                              Name

                              Datetime

                              Token Type and Format

                              Datetime in the following formats:

                              YYYY-MM-DD HH:MM:SS.MMM

                              YYYY-MM-DDTHH:MM:SS.MMM

                              YYYY-MM-DD HH:MM:SS

                              YYYY-MM-DDTHH:MM:SS

                              YYYY-MM-DD

                              From “0600-01-01” to “3337-11-27”, alphabetic digits 0-9, only specific delimiters

                              Input separators (delimiter) between date, month and year

                              . (dot), / (slash), or - (dash)

                              Input separators (delimiter) between hours, minutes and seconds

                              : (colon) only

                              Input separator (delimiter) between date and hour

                              " " (space) or “T” (the letter T)

                              Input separator (delimiter) between seconds and milliseconds

                              . (dot) or , (comma)

                              Supported input data types *1 *2

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Datetime token.

                              Input ValueTokenized ValueComments
                              2009.04.12 12:23:34.3331595.06.19 14:31:51.333YYYY-MM-DD HH:MM:SS.MMM. Milliseconds value is left in the clear.
                              2009.04.12 12:23:341595.06.19 14:31:51YYYY-MM-DD HH:MM:SS with space separator between day and hour.
                              2234.10.12T12:23:232755.08.04T22:33:43YYYY-MM-DDTHH:MM:SS with T separator between day and hour values.
                              • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                              Decimal

                              The Decimal token type tokenizes numbers which may have a precision and scale. The resulting token does not contain any zeros which makes it suitable to store in a decimal data type in a database. Any sign or decimal point delimiter are stripped from the input value before tokenization and put back after tokenization.

                              Tokenization Type Properties

                              Settings

                              Name

                              Decimal

                              Token Type and Format

                              Digits 0 through 9 in input value, 1 thorough 9 in output value

                              The sign (+ or -) and decimal point (. or ,) separator

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              The following table shows examples of the way in which a value will be tokenized with the Decimal token.
                              Input ValueTokenized ValueComments
                              519.02268.68Input value has (.) dot separator.
                              -0.333807-9.893967Input value has sign and (.) dot separator.
                              +,461+,918Input value has sign and (,) comma separator.

                              Email

                              Email token type allows tokenization of an email address. Email token keeps the domain name along with all characters after the “@” sign, and the “@” sign itself in the clear. The local part (i.e. the part before “@”) gets tokenized.

                              Tokenization Type Properties

                              Settings

                              Name

                              Email

                              Token Type and Format

                              Alphabetic and numeric only. The rest characters will be treated as delimiters.

                              Supported input data types

                              Oracle

                              Other Databases

                              CHAR

                              VARCHAR2

                              CHAR

                              VARCHAR

                              1.9 - Known Limitations

                              JDBC Protector known limitations, unsupported features, and workarounds.

                                The JDBC Protector aims to support many database types and versions, and provide compatibility with other Java APIs and libraries. This section lists the known incompatibilities and limitations. Full compatibility with every database and Java library cannot be guaranteed, and additional limitations may not be listed here.

                                The protector has the following limitations:

                                • CLOUDS-1250: When a query ends with a semicolon, an exception is thrown stating “parse failed: Encountered “;””.

                                  • Workaround: Remove the semicolon at the end of the query.
                                • CLOUDS-1324: When inserting a null value into a decimal column, an exception can be thrown stating “Unable to implement JdbcToEnumerableConverter”.

                                  • Workaround: Add a non-null value for the preceding column in the insert query.
                                • CLOUDS-2101: The Protegrity reprotect operation is not currently supported. Please submit an RFE if you require this feature in the JDBC Protector.

                                  • Workaround: Perform an unprotect operation followed by a protect operation.
                                • CLOUDS-2750: A pty_protect() call with an integer data type will cause the query to fail when the mask character is a non-numeric character such as an asterisk, hash, or hyphen.

                                  • Workaround: Either cast the integer value to a char type, or change the mask character to a number.
                                • CLOUDS-3057: The SQL functions CURRENT_ROLE, CURRENT_USER, SESSION_USER, SYSTEM_USER, and USER only work when connecting to a PostgreSQL database.

                                  • Workaround: Often these values can be obtained from other sources or replaced with a literal value.
                                • CLOUDS-3301: The QUARTER and WEEK intervals return incorrect results when used with the PostgreSQL DATE_ADD and DATE_SUBTRACT functions. The CENTURY, DECADE, DOW, DOY, EPOCH, and MILLENNIUM intervals cause an exception to be thrown.

                                  • Workaround: Convert the interval into a DAY, MONTH, or YEAR interval.
                                • CLOUDS-3409: A NullPointerException may be thrown when an UPDATE statement contains a sub-query.

                                  • Workaround: Remove the sub-query from the UPDATE statement and execute it separately. Then use the result of the sub-query in the UPDATE statement.
                                • CLOUDS-3601: The third-party libraries packaged with the Protegrity JDBC driver may be different from the versions of the same libraries used by your application. This can cause exceptions or undefined behavior when the versions do not match.

                                  • Workarounds:
                                    • See this section on how to install Protegrity JDBC Driver using Apache Maven.
                                    • Load the Protegrity JDBC driver in an isolated ClassLoader.
                                • CLOUDS-3602: The Protegrity Application Protector - JDBC includes the SLF4J library for your convenience in case your application does not already have SLF4J. Additional or different JAR files may be required to properly integrate the Protegrity JDBC driver logs with your application logging.

                                  • Workarounds:
                                    • See this section on how to install Protegrity JDBC Driver using Apache Maven.
                                    • Load the Protegrity JDBC driver in an isolated ClassLoader and use the included SLF4J Simple logging.
                                • CLOUDS-3722: Some data type conversions are not supported and throw an exception when they include a protected timestamp column with more than 3 digits of sub-second precision, such as TIMESTAMP(6) or TIMESTAMP(9). This includes converting from / to CHAR, VARCHAR, DATE, TIME, TIMESTAMP(0), and TIMESTAMP(3) columns.

                                  • Workaround: Perform the data type conversion in Java then use the result in your SQL query.
                                • CLOUDS-3783: Sorting on a protected column uses lexicographic ordering based on the Unicode value of each character. This ordering may be different from cleartext columns that use the database’s collation-based ordering which includes locale-specific ordering.

                                  • Workaround: Re-order the rows in Java if locale-specific ordering is required.
                                • CLOUDS-6456: XA transaction support is only available for PostgreSQL.

                                • CLOUDS-6539: When using SQL Server JDBC Driver version 13.x, Protector does not resolve references to the dbo schema. References to dbo result in the error “Object ‘dbo’ not found within ‘adhoc.’”.

                                  • Workaround: Use SQL Server JDBC Driver version 12.x. Alternatively, avoid usage of the dbo schema in SQL queries.
                                • CLOUDS-6749: A DELETE statement with a sub-query is disabled for all vendors other than PostgreSQL.

                                  • Workaround: Remove the sub-query from the DELETE statement and execute it separately. Then use the result of the sub-query to remove matching rows.
                                • CLOUDS-7532: The protector will process data from postgres tables with CITEXT, but CITEXT explicitly written into any input statement will throw an error.

                                  • Workaround: Remove explicit CITEXT specifiers in input statements where they are not required.

                                JDBC API

                                The following JDBC API methods are not implemented and will throw an exception. The application can bypass the JDBC Protector and invoke these methods from the underlying native driver’s connection; however, this will not utilize the JDBC Protector’s transparent protection capabilities.

                                • Connection#abort(Executor)
                                • Connection#createBlob()
                                • Connection#createClob()
                                • Connection#createNClob()
                                • Connection#createSQLXML()
                                • Connection#createStruct(String, Object[])
                                • ResultSet methods that modify the data
                                • ResultSet methods that modify the cursor
                                • ResultSet#isLast()
                                • Statement#getGeneratedKeys()

                                SQL Statements

                                The JDBC Protector can execute DQL and DML statements, such as SELECT, INSERT, UPDATE, and DELETE, in a variety of vendor-specific dialects. While a wide range of vendor-specific SQL extensions are supported, there is no guarantee that the JDBC Protector will handle every SQL statement without modification. The following SQL statements are known to not be supported:

                                • DDL statements such as CREATE, ALTER, or DROP
                                • DCL statements such as GRANT or REVOKE
                                • DELETE statements with a sub-query are supported only on PostgreSQL
                                • UPSERT statements
                                • Some vendor-specific SQL extensions are not supported, including:
                                  • Informix: Sequences are not supported
                                  • MariaDB: Sequences are not supported
                                  • PostgreSQL: ON CONFLICT statements which contain DO UPDATE or ON CONSTRAINT, or which do not use dynamic parameters in a PreparedStatement for protected columns

                                The application can bypass the JDBC Protector and invoke these methods from the underlying native driver’s connection; however, this will not utilize the JDBC Protector’s transparent protection capabilities.

                                Stored Procedures

                                The following limitations apply only to procedure calls:

                                • Procedure calls must use CallableStatement
                                • Literal input values to procedure calls are not protected
                                • Procedure calls that produce a ResultSet are not unprotected

                                1.10 - Troubleshooting

                                JDBC Protector troubleshooting guidance for common errors and corrective actions.

                                  Troubleshooting

                                  Error MessageAction
                                  java.sql.SQLException: No suitable driver found for jdbc:iap:...
                                  1. Verify that the protegrity-jdbc-<version>.jar file has been added to the Java classpath for your application.
                                  2. If your application allows setting the JDBC driver class name, ensure that it has been set to com.protegrity.jdbc.Driver.
                                  3. Try registering the driver by adding the following Java code to your application:
                                    Class.forName("com.protegrity.jdbc.Driver");
                                  Missing "uri" in protect configuration properties
                                  1. Verify that the cloud-protect.properties file has been added to the classpath.
                                  2. Ensure that it contains an uri= entry.
                                  Invalid "uri" in protect configuration propertiesVerify that the protegrity-protect-<platform>-<version>.jar file has been added to the classpath.
                                  AP Java library not found
                                  1. Verify that AP Java has been installed.
                                  2. Ensure that the uri in the cloud-protect.properties file contains rps://esa.example.com:443 followed by the path to your AP Java installation.
                                  Init library failedVerify that the PEP Server is running and is able to connect to ESA.
                                  Policy not available
                                  1. Verify that the PEP Server is able to access your ESA server.
                                  2. Ensure that a policy has been deployed to your PEP Server.
                                  S3 policy file missing IMMUTABLE_POLICY_PACKAGE entryVerify that the uri in the cloud-protect.properties file is the URL of a valid Protegrity policy file.
                                  SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementationAdd an SLF4J binding to your classpath. The Simple binding can be downloaded from Maven.
                                  Failed to encode .. in charaset set ...Set the JVM property calcite.default.charset to the character set you want to use.
                                  Informix: A syntax error has occurred.Verify that DELIMIDENT=Y has been added to your JDBC URL.
                                  SQL SELECT statement with large IN subquery fails with java.lang.StackOverflowErrorAdd InSubqueryThreshold SQL hint to your SELECT statement. This hint tells JDBC Protector to use an alternative SQL query. Sample SQL statement: SELECT /*+ InSubqueryThreshold */ full_name FROM employee WHERE ...

                                  1.11 - Appendix

                                  JDBC Protector appendix reference material and configuration details.

                                    Reference material and configuration details.

                                    Avatica

                                    Apache Avatica is an open-source HTTP/REST server that provides SQL access to an Avatica-compliant client written in other languages. When used with the Protegrity JDBC Protector, it allows applications written in C#, Go, and Python to work with protected data.

                                    A standalone server is provided for running Avatica as a service or as a Docker container. It is recommended to use the latest 1.x version of Avatica with the JDBC Protector. The server can be downloaded from Maven Central.

                                    The following snippet shows an example command-line for running the Avatica standalone server with the JDBC Protector:

                                    java -cp "protegrity-jdbc-<version>.jar:protegrity-protect-linux64-<version>.jar:avatica-standalone-server.jar:mysql-connector-java.jar" -Dprotegrity.cloud.protect.uri=rps://esa.example.com:443 org.apache.calcite.avatica.standalone.StandaloneServer -p 8765 -u "jdbc:iap:mysql://localhost:3306/database"
                                    

                                    The following is a list of clients that support Avatica:

                                    For more information on Apache Avatica, refer to the Avatica documentation.

                                    Connection Properties

                                    The following table describes the JDBC connection properties accepted by the JDBC Protector. The protector uses Apache Calcite and supports Calcite’s configuration properties. The Apache Calcite documentation can be referenced to better understand the options for any of these configuration properties.

                                    PropertyRequiredDefault valueDescription
                                    approximateDistinctCountNofalseSpecifies whether approximate results from COUNT(DISTINCT ...) aggregate functions are acceptable.
                                    approximateTopNNofalseSpecifies whether approximate results from “Top N” queries (ORDER BY aggFun DESC LIMIT n) are acceptable.
                                    approximateDecimalNofalseSpecifies whether approximate results from aggregate functions on DECIMAL types are acceptable.
                                    defaultNullCollationNohighSpecifies how NULL values should be sorted if neither NULLS FIRST nor NULLS LAST are specified. The default, HIGH, sorts NULL values the same as Oracle.
                                    lenientOperatorLookupNofalseSpecifies whether to make create implicit functions if functions do not exist in the operator table, default false.
                                    localeNoExamples of valid locales: ’en’, ’en_US’, ‘de_DE’, ‘_GB’, ’en_US_WIN’, ‘de__POSIX’, ‘fr__MAC’, ‘’.
                                    modelNoURI of the model.
                                    schemaNoName of initial schema.
                                    sparkNofalseSpecifies whether Spark should be used as the engine for processing that cannot be pushed to the source system. If false, then Calcite generates code that implements the Enumerable interface.
                                    timeZoneNoIf the time zone is not set, then the JVM time zone is returned.
                                    typeCoercionNotrueSpecifies whether to make implicit type coercion when type mismatch for validation, default true.

                                    Java Properties

                                    The following table describes Java system properties that can be used to modify the behavior of the JDBC Protector.

                                    PropertyDefault valueDescription
                                    calcite.debugfalseWhen debug mode is activated significantly more information is gathered and printed to STDOUT. It is most commonly used to print and identify problems in generated java code. Debug mode is also used to perform more verifications at runtime, which are not performed during normal execution.
                                    calcite.default.charsetISO-8859-1The name of the default character set.
                                    calcite.default.collation.nameISO-8859-1$en_USThe name of the default collation.
                                    calcite.default.nationalcharsetISO-8859-1The name of the default national character set. May be different from the default charset.
                                    calcite.strict.sqlfalseSpecifies whether to follow the SQL standard strictly.

                                    Model Configuration

                                    The model.json file allows customizing the database schemas exposed by the JDBC Protector and how they map to an underlying JDBC connection.

                                    The example below defines a schema called sales that matches the name of a database in a MySQL server. The defaultSchema property defines which schema to search if a SQL query uses a table that is not fully qualified. The jdbcDriver, jdbcUrl, user, and password properties describe the JDBC connection to a MySQL database that will be protected by the JDBC Protector. The ptyCatalogUri described in Connection Properties can be defined in the operand object.

                                    {
                                        "version": "1.0",
                                        "defaultSchema": "sales",
                                        "schemas": [
                                            {
                                                "name": "sales",
                                                "factory": "com.protegrity.jdbc.JdbcSchemaFactory",
                                                "operand": {
                                                    "jdbcDriver": "com.mysql.jdbc.Driver",
                                                    "jdbcUrl": "jdbc:mysql://localhost:3306/sales",
                                                    "user": "admin",
                                                    "password": "",
                                                    "ptyCatalogUri": "file:/opt/schema.json"
                                                },
                                                "type": "custom"
                                            }
                                        ]
                                    }
                                    

                                    Modify your application’s JDBC URL to use only properties defined in Connection Properties. For example:. For example:

                                    jdbc:iap:model=path/to/model.json;lex=mysql;conformance=mysql_5
                                    

                                    Schema Configuration

                                    The schema.json file describes the database schema and maps columns to data elements from your Protegrity security policy. At a high level, the file lists the databases, tables, and columns that need to be protected. When a query is executed, the JDBC Protector will scan the schema.json file for a matching database, table, and column name ignoring case. If a match is found, the JDBC Protector will use the specified data element to transparently protect and unprotect that column.

                                    The ptyCatalogUri connection property tells the JDBC Protector where to look for the schema.json file. Use a file URI when the schema.json file is a local file. For example, file:/path/dbschema.json indicates the schema configuration is in the local file /path/dbschema.json. Use a classpath URI when the schema.json file is in an application configuration directory or a JAR file that has been added to the JVM classpath. For example, classpath:dbschema.json causes the JDBC Protector to search the classpath for the dbschema.json file.

                                    Each database entry in the schema.json file should contain the name of a database in your database server and a list of table entries. The database name may also refer to a schema name or catalog name if supported by your database server. Each table entry should contain the name of a database table and a list of column entries. Each column entry should contain the name of a table column and the name of a data element within your Protegrity security policy.

                                    The following JSON document shows how the catalog should be constructed:

                                    {"schema":
                                      {"database": [
                                        {"name": "SCHEMA NAME or DATABASE NAME", "table": [
                                          {"name": "TABLE NAME", "column": [
                                            {"name": "COLUMN NAME", "dataelement": "DATA ELEMENT NAME"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    The input and output parameters for stored procedures can also be defined. The following example shows a stored procedure with two input parameters and one output parameter. The input parameters will be protected before the stored procedure is called, and the output parameter will be unprotected before its value is returned to the application.

                                    {"schema":
                                        {"function": [
                                            {"name": "SetLastNameForId", "parameter": [
                                                {"dataelement": null},
                                                {"dataelement": "deTokName"},
                                                {"dataelement": "deTokName"}
                                            ]}
                                        ]}
                                    }
                                    

                                    PostgreSQL

                                    When used with PostgreSQL, the database name must be the PostgreSQL schema name. The PostgreSQL catalog name is not used. The following example shows a JSON catalog for a sales catalog in PostgreSQL containing employees and customers tables.

                                    {"schema":
                                      {"database": [
                                        {"name": "public", "table": [
                                          {"name": "employees", "column": [
                                            {"name": "firstName", "dataelement": "deTokName"},
                                            {"name": "lastName", "dataelement": "deTokName"},
                                            {"name": "email", "dataelement": "deTokEmail"}
                                          ]},
                                          {"name": "customers", "column": [
                                            {"name": "customerName", "dataelement": "deTokName"},
                                            {"name": "city", "dataelement": "deTokCity"},
                                            {"name": "postalCode", "dataelement": "deTokPostCD"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    SQL Server

                                    When used with SQL Server, the database name must be the SQL Server schema name. The SQL Server database name is not used. The following example shows a catalog for a sales database containing employees and customers tables.

                                    {"schema":
                                      {"database": [
                                        {"name": "dbo", "table": [
                                          {"name": "employees", "column": [
                                            {"name": "firstName", "dataelement": "deTokName"},
                                            {"name": "lastName", "dataelement": "deTokName"},
                                            {"name": "email", "dataelement": "deTokEmail"}
                                          ]},
                                          {"name": "customers", "column": [
                                            {"name": "customerName", "dataelement": "deTokName"},
                                            {"name": "city", "dataelement": "deTokCity"},
                                            {"name": "postalCode", "dataelement": "deTokPostCD"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    Stored Procedures

                                    The JDBC Protector supports data protection for stored procedures when used with CallableStatement and dynamic parameters. The input and output parameters should be defined in schema.json along with their associated data elements.

                                    The following Java code provides an example of calling a stored procedure with two input parameters and one output parameter. The value of the second parameter will be protected before the stored procedure is called, and the value of the third parameter will be unprotected before its value is returned to the application.

                                    CallableStatement stmt = connection.prepareCall("call SetLastNameForId(4, ?, ?)");
                                    stmt.setString(1, "Smith");
                                    stmt.registerOutParameter(2, Types.VARCHAR);
                                    stmt.execute();
                                    String fullName = stmt.getString(2);
                                    

                                    Here is the schema.json used for the above example:

                                    {"schema":
                                        {"function": [
                                            {"name": "SetLastNameForId", "parameter": [
                                                {"dataelement": null},
                                                {"dataelement": "deTokName"},
                                                {"dataelement": "deTokName"}
                                            ]}
                                        ]}
                                    }
                                    

                                    Configure Protegrity XA Data Source

                                    This topic describes how to configure JDBC Application Protector for XA transactions.

                                    Prerequisites

                                    • Protegrity JDBC driver installed. See the installation section for driver setup.
                                    • XA is supported since JDBC Application Protector v9.1.0.12.

                                    JDBC Application Protector provides com.protegrity.jdbc.xa.ProtegrityXADataSource for support of XA transactions.

                                    This data source must be configured with the following properties:

                                    • url - JDBC URL data source is connected to
                                    • user - JDBC username (optional)
                                    • password - JDBC password (optional)
                                    • catalogUri - Protegrity catalog URI. For information about configuring catalog URI, see Protegrity Connection Properties.
                                    • protectUri - Protegrity protection service URI. For information about configuring protect URI, see Protegrity Security Policy.
                                    • delegateClassName - Native XA data source class name. Protegrity XA data source will delegate all operations to this class.
                                    • policyUser - Policy user for security operations (optional)

                                    Configuration properties may be initialized using any of the methods described below. The initialization follows a specific precedence order: if the property is not initialized using class fields, it will then be looked up from the JDBC URL. If not found there, initialization will attempt to retrieve the property from java.util.Properties. If still not found, it will check Java system properties, and finally, it will fall back to environment variables.

                                    Configuration options in precedence order:

                                    1. Using class fields
                                    2. Using JDBC URL
                                    3. Using java.util.Properties
                                    4. Using Java system properties
                                    5. Using environment variables

                                    Once initialized, see the following examples for using XA data source. Alternatively, XA data source can be configured using JNDI.

                                    Method 1: Initialize Using Class Fields

                                    public static void main(String[] args) {
                                        var xaDataSource = new ProtegrityXADataSource();
                                        xaDataSource.setUsername("username");
                                        xaDataSource.setPassword("password");
                                        xaDataSource.setDelegateClassName("org.postgresql.xa.PGXADataSource");
                                        xaDataSource.setCatalogUri("file:/pty-schema.json");
                                        xaDataSource.setProtectUri("rps://esa.example.com:443");
                                        xaDataSource.setUrl("jdbc:postgresql://host:port/database");
                                        xaDataSource.setPolicyUser("policy-user");
                                    }
                                    

                                    Method 2: Initialize Using a JDBC URL

                                    The following parameters are available:

                                    • user
                                    • password
                                    • ptyCatalogUri
                                    • ptyProtectUri
                                    • delegateClassName
                                    • ptyPolicyUser
                                    public static void main(String[] args) {
                                        var xaDataSource = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    }
                                    

                                    Method 3: Initialize Using java.util.Properties

                                    import java.util.Properties;
                                    
                                    public static void main(String[] args) {
                                        var properties = new Properties();
                                        properties.put(ProtegrityXADataSource.PropertyNames.URL, "jdbc:postgresql://host:port/database");
                                        properties.put(ProtegrityXADataSource.PropertyNames.USER, "username");
                                        properties.put(ProtegrityXADataSource.PropertyNames.PASSWORD, "password");
                                        properties.put(ProtegrityXADataSource.PropertyNames.CATALOG_URI, "file:/pty-schema.json");
                                        properties.put(ProtegrityXADataSource.PropertyNames.PROTECT_URI, "rps://esa.example.com:443");
                                        properties.put(ProtegrityXADataSource.PropertyNames.DELEGATE_CLASS_NAME, "org.postgresql.xa.PGXADataSource");
                                        properties.put(ProtegrityXADataSource.PropertyNames.POLICY_USER, "policy-user");
                                    
                                        var xaDataSource = new ProtegrityXADataSource(properties);
                                    }
                                    

                                    Method 4: Initialize Using Java System Properties

                                    public static void main(String[] args) {
                                        System.setProperty("com.protegrity.jdbc.url", "jdbc:postgresql://host:port/database");
                                        System.setProperty("com.protegrity.jdbc.user", "username");
                                        System.setProperty("com.protegrity.jdbc.password", "password");
                                        System.setProperty("com.protegrity.jdbc.delegateClassName", "org.postgresql.xa.PGXADataSource");
                                        System.setProperty("com.protegrity.jdbc.ptyCatalogUri", "file:/pty-schema.json");
                                        System.setProperty("com.protegrity.jdbc.ptyProtectUri", "rps://esa.example.com:443");
                                        System.setProperty("com.protegrity.jdbc.ptyPolicyUser", "policy-user");
                                    
                                        var xaDataSource = new ProtegrityXADataSource();
                                    }
                                    

                                    Or pass them as command-line arguments:

                                    java -Dcom.protegrity.jdbc.url="jdbc:postgresql://localhost:32779/database_name" \
                                         -Dcom.protegrity.jdbc.delegateClassName="org.postgresql.xa.PGXADataSource" \
                                         -Dcom.protegrity.jdbc.user="username" \
                                         -Dcom.protegrity.jdbc.password="password" \
                                         -Dcom.protegrity.jdbc.ptyCatalogUri="file:/pty-schema.json" \
                                         -Dcom.protegrity.jdbc.ptyProtectUri="file:/pty-policy" \
                                         -Dcom.protegrity.jdbc.ptyPolicyUser="policy-user" \
                                         -jar your-application.jar
                                    

                                    Method 5: Initialize Using Environment Variables

                                    Set the following environment variables:

                                    • PTY_JDBC_URL
                                    • PTY_JDBC_USER
                                    • PTY_JDBC_PASSWORD
                                    • PTY_JDBC_CATALOG_URI
                                    • PTY_JDBC_PROTECT_URI
                                    • PTY_JDBC_DELEGATE_CLASS_NAME
                                    • PTY_JDBC_POLICY_USER

                                    Set environment variables:

                                    export PTY_JDBC_URL="jdbc:postgresql://host:port/database"
                                    export PTY_JDBC_USER="username"
                                    export PTY_JDBC_PASSWORD="password"
                                    export PTY_JDBC_CATALOG_URI="file:/pty-schema.json"
                                    export PTY_JDBC_PROTECT_URI="rps://esa.example.com:443"
                                    export PTY_JDBC_DELEGATE_CLASS_NAME="org.postgresql.xa.PGXADataSource"
                                    export PTY_JDBC_POLICY_USER="policy-user"
                                    

                                    Initialize:

                                    public static void main(String[] args) {
                                        var xaDataSource = new ProtegrityXADataSource();
                                    }
                                    

                                    Using the XADataSource

                                    After initialization, you can use the XADataSource as follows:

                                    import java.sql.Connection;
                                    import java.sql.ResultSet;
                                    import java.sql.SQLException;
                                    import javax.sql.XADataSource;
                                    
                                    static void testConnection(XADataSource xaDataSource) throws SQLException {
                                        try (Connection connection = xaDataSource.getXAConnection().getConnection()) {
                                            ResultSet resultSet = connection.prepareStatement("SELECT ...").executeQuery();
                                            // Use result set
                                        }
                                    }
                                    

                                    Using XADataSource with Transaction Manager

                                    To benefit from distributed transactions, use this XADataSource with a transaction manager such as Atomikos:

                                    import com.atomikos.icatch.jta.UserTransactionManager;
                                    import com.atomikos.jdbc.AtomikosDataSourceBean;
                                    
                                    void performXaTransaction() throws Exception {
                                        UserTransactionManager transactionManager = new UserTransactionManager();
                                    
                                        // Initialize data sources
                                        var xaDataSource1 = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database1" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    
                                        var xaDataSource2 = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database2" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    
                                        // Configure Atomikos
                                        AtomikosDataSourceBean dataSourceBean1 = new AtomikosDataSourceBean();
                                        dataSourceBean1.setUniqueResourceName("Data Source 1");
                                        dataSourceBean1.setXaDataSource(xaDataSource1);
                                    
                                        AtomikosDataSourceBean dataSourceBean2 = new AtomikosDataSourceBean();
                                        dataSourceBean2.setUniqueResourceName("Data Source 2");
                                        dataSourceBean2.setXaDataSource(xaDataSource2);
                                    
                                        // Execute transaction
                                        try (var connection1 = dataSourceBean1.getConnection();
                                             var connection2 = dataSourceBean2.getConnection()) {
                                            transactionManager.begin();
                                    
                                            var statement1 = connection1.prepareStatement("INSERT INTO test_table (id, name) VALUES (?, ?)");
                                            statement1.setInt(1, 1);
                                            statement1.setString(2, "Alice");
                                            statement1.executeUpdate();
                                    
                                            // Use connection2 operations as needed
                                    
                                            transactionManager.commit();
                                        } catch (Exception exception) {
                                            transactionManager.rollback();
                                            throw exception;
                                        }
                                    }
                                    

                                    Initialize Using JNDI

                                    Example JNDI configuration for WildFly in standalone.xml:

                                    <datasources>
                                      <xa-datasource jndi-name="java:/XADataSource" pool-name="XAPool" enabled="true" use-java-context="true" statistics-enabled="true">
                                        <xa-datasource-property name="url">
                                          jdbc:postgresql://localhost:5434/db
                                        </xa-datasource-property>
                                        <xa-datasource-property name="username">
                                          anthony.stark
                                        </xa-datasource-property>
                                        <xa-datasource-property name="password">
                                          1r0nM4n
                                        </xa-datasource-property>
                                        <xa-datasource-property name="catalogUri">
                                          file:/opt/protegrity/pty-schema.json
                                        </xa-datasource-property>
                                        <xa-datasource-property name="protectUri">
                                          rps://esa.example.com:443
                                        </xa-datasource-property>
                                        <xa-datasource-property name="delegateClassName">
                                          org.postgresql.xa.PGXADataSource
                                        </xa-datasource-property>
                                        <xa-datasource-property name="policyUser">
                                          policy-user
                                        </xa-datasource-property>
                                        <driver>protegrity</driver>
                                      </xa-datasource>
                                    
                                      <drivers>
                                        <driver name="protegrity" module="com.protegrity">
                                          <xa-datasource-class>com.protegrity.jdbc.xa.ProtegrityXADataSource</xa-datasource-class>
                                        </driver>
                                      </drivers>
                                    </datasources>
                                    

                                    Look up XA data source in your application code using JNDI context:

                                    import javax.naming.InitialContext;
                                    import javax.sql.DataSource;
                                    import java.sql.Connection;
                                    import java.sql.ResultSet;
                                    import java.sql.Statement;
                                    
                                    void testConnection() throws Exception {
                                        InitialContext ctx = new InitialContext();
                                        DataSource xaDataSource = (DataSource) ctx.lookup("java:/XADataSource");
                                    
                                        try (Connection conn = xaDataSource.getConnection();
                                             Statement stmt = conn.createStatement();
                                             ResultSet rs = stmt.executeQuery("SELECT ...")) {
                                            // Use result set
                                        }
                                    }
                                    

                                    1.12 -

                                    Avatica

                                    Apache Avatica is an open-source HTTP/REST server that provides SQL access to an Avatica-compliant client written in other languages. When used with the Protegrity JDBC Protector, it allows applications written in C#, Go, and Python to work with protected data.

                                    A standalone server is provided for running Avatica as a service or as a Docker container. It is recommended to use the latest 1.x version of Avatica with the JDBC Protector. The server can be downloaded from Maven Central.

                                    The following snippet shows an example command-line for running the Avatica standalone server with the JDBC Protector:

                                    java -cp "protegrity-jdbc-<version>.jar:protegrity-protect-linux64-<version>.jar:avatica-standalone-server.jar:mysql-connector-java.jar" -Dprotegrity.cloud.protect.uri=rps://esa.example.com:443 org.apache.calcite.avatica.standalone.StandaloneServer -p 8765 -u "jdbc:iap:mysql://localhost:3306/database"
                                    

                                    The following is a list of clients that support Avatica:

                                    For more information on Apache Avatica, refer to the Avatica documentation.

                                    1.13 -

                                    Connection Properties

                                    The following table describes the JDBC connection properties accepted by the JDBC Protector. The protector uses Apache Calcite and supports Calcite’s configuration properties. The Apache Calcite documentation can be referenced to better understand the options for any of these configuration properties.

                                    PropertyRequiredDefault valueDescription
                                    approximateDistinctCountNofalseSpecifies whether approximate results from COUNT(DISTINCT ...) aggregate functions are acceptable.
                                    approximateTopNNofalseSpecifies whether approximate results from “Top N” queries (ORDER BY aggFun DESC LIMIT n) are acceptable.
                                    approximateDecimalNofalseSpecifies whether approximate results from aggregate functions on DECIMAL types are acceptable.
                                    defaultNullCollationNohighSpecifies how NULL values should be sorted if neither NULLS FIRST nor NULLS LAST are specified. The default, HIGH, sorts NULL values the same as Oracle.
                                    lenientOperatorLookupNofalseSpecifies whether to make create implicit functions if functions do not exist in the operator table, default false.
                                    localeNoExamples of valid locales: ’en’, ’en_US’, ‘de_DE’, ‘_GB’, ’en_US_WIN’, ‘de__POSIX’, ‘fr__MAC’, ‘’.
                                    modelNoURI of the model.
                                    schemaNoName of initial schema.
                                    sparkNofalseSpecifies whether Spark should be used as the engine for processing that cannot be pushed to the source system. If false, then Calcite generates code that implements the Enumerable interface.
                                    timeZoneNoIf the time zone is not set, then the JVM time zone is returned.
                                    typeCoercionNotrueSpecifies whether to make implicit type coercion when type mismatch for validation, default true.

                                    1.14 -

                                    Java Properties

                                    The following table describes Java system properties that can be used to modify the behavior of the JDBC Protector.

                                    PropertyDefault valueDescription
                                    calcite.debugfalseWhen debug mode is activated significantly more information is gathered and printed to STDOUT. It is most commonly used to print and identify problems in generated java code. Debug mode is also used to perform more verifications at runtime, which are not performed during normal execution.
                                    calcite.default.charsetISO-8859-1The name of the default character set.
                                    calcite.default.collation.nameISO-8859-1$en_USThe name of the default collation.
                                    calcite.default.nationalcharsetISO-8859-1The name of the default national character set. May be different from the default charset.
                                    calcite.strict.sqlfalseSpecifies whether to follow the SQL standard strictly.

                                    1.15 -

                                    Model Configuration

                                    The model.json file allows customizing the database schemas exposed by the JDBC Protector and how they map to an underlying JDBC connection.

                                    The example below defines a schema called sales that matches the name of a database in a MySQL server. The defaultSchema property defines which schema to search if a SQL query uses a table that is not fully qualified. The jdbcDriver, jdbcUrl, user, and password properties describe the JDBC connection to a MySQL database that will be protected by the JDBC Protector. The ptyCatalogUri described in Connection Properties can be defined in the operand object.

                                    {
                                        "version": "1.0",
                                        "defaultSchema": "sales",
                                        "schemas": [
                                            {
                                                "name": "sales",
                                                "factory": "com.protegrity.jdbc.JdbcSchemaFactory",
                                                "operand": {
                                                    "jdbcDriver": "com.mysql.jdbc.Driver",
                                                    "jdbcUrl": "jdbc:mysql://localhost:3306/sales",
                                                    "user": "admin",
                                                    "password": "",
                                                    "ptyCatalogUri": "file:/opt/schema.json"
                                                },
                                                "type": "custom"
                                            }
                                        ]
                                    }
                                    

                                    Modify your application’s JDBC URL to use only properties defined in Connection Properties. For example:. For example:

                                    jdbc:iap:model=path/to/model.json;lex=mysql;conformance=mysql_5
                                    

                                    1.16 -

                                    Schema Configuration

                                    The schema.json file describes the database schema and maps columns to data elements from your Protegrity security policy. At a high level, the file lists the databases, tables, and columns that need to be protected. When a query is executed, the JDBC Protector will scan the schema.json file for a matching database, table, and column name ignoring case. If a match is found, the JDBC Protector will use the specified data element to transparently protect and unprotect that column.

                                    The ptyCatalogUri connection property tells the JDBC Protector where to look for the schema.json file. Use a file URI when the schema.json file is a local file. For example, file:/path/dbschema.json indicates the schema configuration is in the local file /path/dbschema.json. Use a classpath URI when the schema.json file is in an application configuration directory or a JAR file that has been added to the JVM classpath. For example, classpath:dbschema.json causes the JDBC Protector to search the classpath for the dbschema.json file.

                                    Each database entry in the schema.json file should contain the name of a database in your database server and a list of table entries. The database name may also refer to a schema name or catalog name if supported by your database server. Each table entry should contain the name of a database table and a list of column entries. Each column entry should contain the name of a table column and the name of a data element within your Protegrity security policy.

                                    The following JSON document shows how the catalog should be constructed:

                                    {"schema":
                                      {"database": [
                                        {"name": "SCHEMA NAME or DATABASE NAME", "table": [
                                          {"name": "TABLE NAME", "column": [
                                            {"name": "COLUMN NAME", "dataelement": "DATA ELEMENT NAME"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    The input and output parameters for stored procedures can also be defined. The following example shows a stored procedure with two input parameters and one output parameter. The input parameters will be protected before the stored procedure is called, and the output parameter will be unprotected before its value is returned to the application.

                                    {"schema":
                                        {"function": [
                                            {"name": "SetLastNameForId", "parameter": [
                                                {"dataelement": null},
                                                {"dataelement": "deTokName"},
                                                {"dataelement": "deTokName"}
                                            ]}
                                        ]}
                                    }
                                    

                                    PostgreSQL

                                    When used with PostgreSQL, the database name must be the PostgreSQL schema name. The PostgreSQL catalog name is not used. The following example shows a JSON catalog for a sales catalog in PostgreSQL containing employees and customers tables.

                                    {"schema":
                                      {"database": [
                                        {"name": "public", "table": [
                                          {"name": "employees", "column": [
                                            {"name": "firstName", "dataelement": "deTokName"},
                                            {"name": "lastName", "dataelement": "deTokName"},
                                            {"name": "email", "dataelement": "deTokEmail"}
                                          ]},
                                          {"name": "customers", "column": [
                                            {"name": "customerName", "dataelement": "deTokName"},
                                            {"name": "city", "dataelement": "deTokCity"},
                                            {"name": "postalCode", "dataelement": "deTokPostCD"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    SQL Server

                                    When used with SQL Server, the database name must be the SQL Server schema name. The SQL Server database name is not used. The following example shows a catalog for a sales database containing employees and customers tables.

                                    {"schema":
                                      {"database": [
                                        {"name": "dbo", "table": [
                                          {"name": "employees", "column": [
                                            {"name": "firstName", "dataelement": "deTokName"},
                                            {"name": "lastName", "dataelement": "deTokName"},
                                            {"name": "email", "dataelement": "deTokEmail"}
                                          ]},
                                          {"name": "customers", "column": [
                                            {"name": "customerName", "dataelement": "deTokName"},
                                            {"name": "city", "dataelement": "deTokCity"},
                                            {"name": "postalCode", "dataelement": "deTokPostCD"}
                                          ]}
                                        ]}
                                      ]}
                                    }
                                    

                                    1.17 -

                                    Stored Procedures

                                    The JDBC Protector supports data protection for stored procedures when used with CallableStatement and dynamic parameters. The input and output parameters should be defined in schema.json along with their associated data elements.

                                    The following Java code provides an example of calling a stored procedure with two input parameters and one output parameter. The value of the second parameter will be protected before the stored procedure is called, and the value of the third parameter will be unprotected before its value is returned to the application.

                                    CallableStatement stmt = connection.prepareCall("call SetLastNameForId(4, ?, ?)");
                                    stmt.setString(1, "Smith");
                                    stmt.registerOutParameter(2, Types.VARCHAR);
                                    stmt.execute();
                                    String fullName = stmt.getString(2);
                                    

                                    Here is the schema.json used for the above example:

                                    {"schema":
                                        {"function": [
                                            {"name": "SetLastNameForId", "parameter": [
                                                {"dataelement": null},
                                                {"dataelement": "deTokName"},
                                                {"dataelement": "deTokName"}
                                            ]}
                                        ]}
                                    }
                                    

                                    1.18 -

                                    Configure Protegrity XA Data Source

                                    This topic describes how to configure JDBC Application Protector for XA transactions.

                                    Prerequisites

                                    • Protegrity JDBC driver installed. See the installation section for driver setup.
                                    • XA is supported since JDBC Application Protector v9.1.0.12.

                                    JDBC Application Protector provides com.protegrity.jdbc.xa.ProtegrityXADataSource for support of XA transactions.

                                    This data source must be configured with the following properties:

                                    • url - JDBC URL data source is connected to
                                    • user - JDBC username (optional)
                                    • password - JDBC password (optional)
                                    • catalogUri - Protegrity catalog URI. For information about configuring catalog URI, see Protegrity Connection Properties.
                                    • protectUri - Protegrity protection service URI. For information about configuring protect URI, see Protegrity Security Policy.
                                    • delegateClassName - Native XA data source class name. Protegrity XA data source will delegate all operations to this class.
                                    • policyUser - Policy user for security operations (optional)

                                    Configuration properties may be initialized using any of the methods described below. The initialization follows a specific precedence order: if the property is not initialized using class fields, it will then be looked up from the JDBC URL. If not found there, initialization will attempt to retrieve the property from java.util.Properties. If still not found, it will check Java system properties, and finally, it will fall back to environment variables.

                                    Configuration options in precedence order:

                                    1. Using class fields
                                    2. Using JDBC URL
                                    3. Using java.util.Properties
                                    4. Using Java system properties
                                    5. Using environment variables

                                    Once initialized, see the following examples for using XA data source. Alternatively, XA data source can be configured using JNDI.

                                    Method 1: Initialize Using Class Fields

                                    public static void main(String[] args) {
                                        var xaDataSource = new ProtegrityXADataSource();
                                        xaDataSource.setUsername("username");
                                        xaDataSource.setPassword("password");
                                        xaDataSource.setDelegateClassName("org.postgresql.xa.PGXADataSource");
                                        xaDataSource.setCatalogUri("file:/pty-schema.json");
                                        xaDataSource.setProtectUri("rps://esa.example.com:443");
                                        xaDataSource.setUrl("jdbc:postgresql://host:port/database");
                                        xaDataSource.setPolicyUser("policy-user");
                                    }
                                    

                                    Method 2: Initialize Using a JDBC URL

                                    The following parameters are available:

                                    • user
                                    • password
                                    • ptyCatalogUri
                                    • ptyProtectUri
                                    • delegateClassName
                                    • ptyPolicyUser
                                    public static void main(String[] args) {
                                        var xaDataSource = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    }
                                    

                                    Method 3: Initialize Using java.util.Properties

                                    import java.util.Properties;
                                    
                                    public static void main(String[] args) {
                                        var properties = new Properties();
                                        properties.put(ProtegrityXADataSource.PropertyNames.URL, "jdbc:postgresql://host:port/database");
                                        properties.put(ProtegrityXADataSource.PropertyNames.USER, "username");
                                        properties.put(ProtegrityXADataSource.PropertyNames.PASSWORD, "password");
                                        properties.put(ProtegrityXADataSource.PropertyNames.CATALOG_URI, "file:/pty-schema.json");
                                        properties.put(ProtegrityXADataSource.PropertyNames.PROTECT_URI, "rps://esa.example.com:443");
                                        properties.put(ProtegrityXADataSource.PropertyNames.DELEGATE_CLASS_NAME, "org.postgresql.xa.PGXADataSource");
                                        properties.put(ProtegrityXADataSource.PropertyNames.POLICY_USER, "policy-user");
                                    
                                        var xaDataSource = new ProtegrityXADataSource(properties);
                                    }
                                    

                                    Method 4: Initialize Using Java System Properties

                                    public static void main(String[] args) {
                                        System.setProperty("com.protegrity.jdbc.url", "jdbc:postgresql://host:port/database");
                                        System.setProperty("com.protegrity.jdbc.user", "username");
                                        System.setProperty("com.protegrity.jdbc.password", "password");
                                        System.setProperty("com.protegrity.jdbc.delegateClassName", "org.postgresql.xa.PGXADataSource");
                                        System.setProperty("com.protegrity.jdbc.ptyCatalogUri", "file:/pty-schema.json");
                                        System.setProperty("com.protegrity.jdbc.ptyProtectUri", "rps://esa.example.com:443");
                                        System.setProperty("com.protegrity.jdbc.ptyPolicyUser", "policy-user");
                                    
                                        var xaDataSource = new ProtegrityXADataSource();
                                    }
                                    

                                    Or pass them as command-line arguments:

                                    java -Dcom.protegrity.jdbc.url="jdbc:postgresql://localhost:32779/database_name" \
                                         -Dcom.protegrity.jdbc.delegateClassName="org.postgresql.xa.PGXADataSource" \
                                         -Dcom.protegrity.jdbc.user="username" \
                                         -Dcom.protegrity.jdbc.password="password" \
                                         -Dcom.protegrity.jdbc.ptyCatalogUri="file:/pty-schema.json" \
                                         -Dcom.protegrity.jdbc.ptyProtectUri="file:/pty-policy" \
                                         -Dcom.protegrity.jdbc.ptyPolicyUser="policy-user" \
                                         -jar your-application.jar
                                    

                                    Method 5: Initialize Using Environment Variables

                                    Set the following environment variables:

                                    • PTY_JDBC_URL
                                    • PTY_JDBC_USER
                                    • PTY_JDBC_PASSWORD
                                    • PTY_JDBC_CATALOG_URI
                                    • PTY_JDBC_PROTECT_URI
                                    • PTY_JDBC_DELEGATE_CLASS_NAME
                                    • PTY_JDBC_POLICY_USER

                                    Set environment variables:

                                    export PTY_JDBC_URL="jdbc:postgresql://host:port/database"
                                    export PTY_JDBC_USER="username"
                                    export PTY_JDBC_PASSWORD="password"
                                    export PTY_JDBC_CATALOG_URI="file:/pty-schema.json"
                                    export PTY_JDBC_PROTECT_URI="rps://esa.example.com:443"
                                    export PTY_JDBC_DELEGATE_CLASS_NAME="org.postgresql.xa.PGXADataSource"
                                    export PTY_JDBC_POLICY_USER="policy-user"
                                    

                                    Initialize:

                                    public static void main(String[] args) {
                                        var xaDataSource = new ProtegrityXADataSource();
                                    }
                                    

                                    Using the XADataSource

                                    After initialization, you can use the XADataSource as follows:

                                    import java.sql.Connection;
                                    import java.sql.ResultSet;
                                    import java.sql.SQLException;
                                    import javax.sql.XADataSource;
                                    
                                    static void testConnection(XADataSource xaDataSource) throws SQLException {
                                        try (Connection connection = xaDataSource.getXAConnection().getConnection()) {
                                            ResultSet resultSet = connection.prepareStatement("SELECT ...").executeQuery();
                                            // Use result set
                                        }
                                    }
                                    

                                    Using XADataSource with Transaction Manager

                                    To benefit from distributed transactions, use this XADataSource with a transaction manager such as Atomikos:

                                    import com.atomikos.icatch.jta.UserTransactionManager;
                                    import com.atomikos.jdbc.AtomikosDataSourceBean;
                                    
                                    void performXaTransaction() throws Exception {
                                        UserTransactionManager transactionManager = new UserTransactionManager();
                                    
                                        // Initialize data sources
                                        var xaDataSource1 = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database1" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    
                                        var xaDataSource2 = ProtegrityXADataSource.fromJdbcUrl(
                                            "jdbc:postgresql://host:port/database2" +
                                            "?user=user" +
                                            "&password=password" +
                                            "&ptyCatalogUri=file:/pty-schema.json" +
                                            "&ptyProtectUri=rps://esa.example.com:443" +
                                            "&delegateClassName=org.postgresql.xa.PGXADataSource" +
                                            "&ptyPolicyUser=policy-user"
                                        );
                                    
                                        // Configure Atomikos
                                        AtomikosDataSourceBean dataSourceBean1 = new AtomikosDataSourceBean();
                                        dataSourceBean1.setUniqueResourceName("Data Source 1");
                                        dataSourceBean1.setXaDataSource(xaDataSource1);
                                    
                                        AtomikosDataSourceBean dataSourceBean2 = new AtomikosDataSourceBean();
                                        dataSourceBean2.setUniqueResourceName("Data Source 2");
                                        dataSourceBean2.setXaDataSource(xaDataSource2);
                                    
                                        // Execute transaction
                                        try (var connection1 = dataSourceBean1.getConnection();
                                             var connection2 = dataSourceBean2.getConnection()) {
                                            transactionManager.begin();
                                    
                                            var statement1 = connection1.prepareStatement("INSERT INTO test_table (id, name) VALUES (?, ?)");
                                            statement1.setInt(1, 1);
                                            statement1.setString(2, "Alice");
                                            statement1.executeUpdate();
                                    
                                            // Use connection2 operations as needed
                                    
                                            transactionManager.commit();
                                        } catch (Exception exception) {
                                            transactionManager.rollback();
                                            throw exception;
                                        }
                                    }
                                    

                                    Initialize Using JNDI

                                    Example JNDI configuration for WildFly in standalone.xml:

                                    <datasources>
                                      <xa-datasource jndi-name="java:/XADataSource" pool-name="XAPool" enabled="true" use-java-context="true" statistics-enabled="true">
                                        <xa-datasource-property name="url">
                                          jdbc:postgresql://localhost:5434/db
                                        </xa-datasource-property>
                                        <xa-datasource-property name="username">
                                          anthony.stark
                                        </xa-datasource-property>
                                        <xa-datasource-property name="password">
                                          1r0nM4n
                                        </xa-datasource-property>
                                        <xa-datasource-property name="catalogUri">
                                          file:/opt/protegrity/pty-schema.json
                                        </xa-datasource-property>
                                        <xa-datasource-property name="protectUri">
                                          rps://esa.example.com:443
                                        </xa-datasource-property>
                                        <xa-datasource-property name="delegateClassName">
                                          org.postgresql.xa.PGXADataSource
                                        </xa-datasource-property>
                                        <xa-datasource-property name="policyUser">
                                          policy-user
                                        </xa-datasource-property>
                                        <driver>protegrity</driver>
                                      </xa-datasource>
                                    
                                      <drivers>
                                        <driver name="protegrity" module="com.protegrity">
                                          <xa-datasource-class>com.protegrity.jdbc.xa.ProtegrityXADataSource</xa-datasource-class>
                                        </driver>
                                      </drivers>
                                    </datasources>
                                    

                                    Look up XA data source in your application code using JNDI context:

                                    import javax.naming.InitialContext;
                                    import javax.sql.DataSource;
                                    import java.sql.Connection;
                                    import java.sql.ResultSet;
                                    import java.sql.Statement;
                                    
                                    void testConnection() throws Exception {
                                        InitialContext ctx = new InitialContext();
                                        DataSource xaDataSource = (DataSource) ctx.lookup("java:/XADataSource");
                                    
                                        try (Connection conn = xaDataSource.getConnection();
                                             Statement stmt = conn.createStatement();
                                             ResultSet rs = stmt.executeQuery("SELECT ...")) {
                                            // Use result set
                                        }
                                    }
                                    

                                    1.19 -

                                    The handling of audit records depends on how your policy is deployed. When using AP Java, audit logs are handled according to the PEP Server configuration. When using the Cloud API, audit records are recorded to CloudWatch. When using the Cloud Protect Agent, audit records are sent to the SLF4J logger. Application logs are always sent to the SLF4J logger.

                                    The audit records sent to SLF4J are written as JSON records. Protection operations are batched together when possible, and an audit record is written for each batch.

                                    Audit Record Fields

                                    The fields are described in the following table.

                                    Field

                                    Description

                                    additional_info.description

                                    An error description or success message

                                    cnt

                                    Number of values processed in the batch

                                    correlationid

                                    The request id or query id set by the client application

                                    level

                                    INFO for successful, WARNING for permission denied, ERROR for errors

                                    logtype

                                    Always Protection

                                    origin.hostname

                                    The hostname of the system that generated the log entry

                                    client.ip

                                    IP address of the machine where the log is generated

                                    client.username

                                    User who triggered an event which generated the log

                                    origin.time_utc

                                    UTC timestamp of the request using the timezone of Protect service deployment

                                    process.id

                                    Process ID of the event that generated the log

                                    process.thread_id

                                    Thread ID of the event that generated the log

                                    protection.audit_code

                                    The audit code of the protect operation. List of possible errors and corresponding audit codes: - Authorized Protect: 6

                                    • Authorized Unprotect: 8
                                    • Unauthorized Protect/Unprotect: 3
                                    • User not found: 1
                                    • Data element not found: 2

                                    protection.dataelement

                                    The security policy field element requested

                                    protection.operation

                                    Protect or unprotect operation requested

                                    protection.policy_user

                                    User that performed the protect or unprotect

                                    protector.family

                                    Protector family name for which the log was generated

                                    protector.vendor

                                    Protector vendor name for which the log was generated

                                    protector.version

                                    Product build number

                                    protector.pcc_version

                                    Core PCC version

                                    protector.core_version

                                    PEP server version

                                    signature.checksum

                                    Hash value of the signature key ID used to sign the log message when the log is generated

                                    signature.key_id

                                    Key used to sign the log message when the log is generated

                                    Example Audit Records

                                    The following are sample audit messages:

                                    Protect Success:

                                    {
                                          "additional_info": {
                                            "description": "Data protect operation was successful."
                                          },
                                          "cnt": 4000,
                                          "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                          "logtype": "Protection",
                                          "level": "INFO",
                                          "origin": {
                                            "hostname": "localhost",
                                            "time_utc": 1635363966
                                          },
                                          "protection": {
                                            "dataelement": "deAddress",
                                            "operation": "Protect",
                                            "audit_code": 6,
                                            "policy_user": "test_user"
                                          },
                                          "process": {
                                            "id": "1",
                                            "thread_id": "849348352"
                                          },
                                          "client": {},
                                          "protector": {
                                            "family": "IAP Lambda",
                                            "version": "1.0.0",
                                            "vendor": "Cloud Protect",
                                            "pcc_version": "3.3.0.5",
                                            "core_version": "1.1.0"
                                          },
                                          "signature": {
                                            "key_id": "95f5a194-b0a4-4351-a",
                                            "checksum": "B324AF7C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                          }
                                        }
                                    

                                    User permission denied:

                                    {
                                          "additional_info": {
                                            "description": "The user does not have the appropriate permissions to perform the requested operation."
                                          },
                                          "cnt": 4000,
                                          "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                          "logtype": "Protection",
                                          "level": "ERROR",
                                          "origin": {
                                            "hostname": "localhost",
                                            "time_utc": 1635363966
                                          },
                                          "protection": {
                                            "dataelement": "deAddress",
                                            "operation": "Protect",
                                            "audit_code": 3,
                                            "policy_user": "test_user"
                                          },
                                          "process": {
                                            "id": "1",
                                            "thread_id": "849348352"
                                          },
                                          "client": {},
                                          "protector": {
                                            "family": "IAP Lambda",
                                            "version": "1.0.0",
                                            "vendor": "Cloud Protect",
                                            "pcc_version": "3.3.0.5",
                                            "core_version": "1.1.0"
                                          },
                                          "signature": {
                                            "key_id": "95f5a194-b0a4-4351-a",
                                            "checksum": "A216797C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                          }
                                        }
                                    

                                    Data element not found:

                                    {
                                          "additional_info": {
                                            "description": "The data element could not be found in the policy in shared memory."
                                          },
                                          "cnt": 4000,
                                          "correlationid": "sf-query-id:01978dbc-0582-d7e4-0000-002a3603a20d",
                                          "logtype": "Protection",
                                          "level": "ERROR",
                                          "origin": {
                                            "hostname": "localhost",
                                            "time_utc": 1635363966
                                          },
                                          "protection": {
                                            "dataelement": "deAddress",
                                            "operation": "Protect",
                                            "audit_code": 2,
                                            "policy_user": "test_user"
                                          },
                                          "process": {
                                            "id": "1",
                                            "thread_id": "849348352"
                                          },
                                          "client": {},
                                          "protector": {
                                            "family": "IAP Lambda",
                                            "version": "1.0.0",
                                            "vendor": "Cloud Protect",
                                            "pcc_version": "3.3.0.5",
                                            "core_version": "1.1.0"
                                          },
                                          "signature": {
                                            "key_id": "95f5a194-b0a4-4351-a",
                                            "checksum": "AF09217C56944D91C47847A77C0367C594C0B948E7E75654B889571BD4F60A71"
                                          }
                                        }
                                    

                                    1.20 -

                                    Connection Properties

                                    The table below describes the JDBC connection properties accepted by the JDBC Protector. The optimal values are automatically applied for JDBC URLs that start with any of the following:

                                    • jdbc:iap:awsathena:
                                    • jdbc:iap:bigquery:
                                    • jdbc:iap:db2:
                                    • jdbc:iap:informix-direct:
                                    • jdbc:iap:informix-sqli:
                                    • jdbc:iap:mariadb:
                                    • jdbc:iap:mysql:
                                    • jdbc:iap:oracle:
                                    • jdbc:iap:postgresql:
                                    • jdbc:iap:presto:
                                    • jdbc:iap:sqlserver:

                                    To use a different JDBC URL, adjust the connection properties below to match your requirements:

                                    Property

                                    Required

                                    Default value

                                    Description

                                    conformance

                                    No

                                    default

                                    Controls the semantics of ISO standard SQL features that are implemented in non-standard ways in some other system. For the possible values, refer to the SQL Conformance section.

                                    fun

                                    No

                                    standard

                                    Collection of built-in functions and operators. Valid values include “standard”, “bigquery”, “mysql”, “oracle”, “postgresql” and “spatial”, and also comma-separated lists, for example “oracle,spatial”.

                                    lex

                                    No

                                    oracle

                                    Lexical policy describes how identifiers are quoted, whether they are converted to upper or lower-case, or case insensitivity. For the possible values, refer to the Lexical Policy section.

                                    ptyBatchSize

                                    No

                                    1000

                                    Number of SELECT query results to include in a single batch of protect or unprotect operations. Larger values can improve the performance of the protect or unprotect operation, but will increase the time before the first result is returned to the application.

                                    ptyCatalogUri

                                    No

                                    Location of the Protegrity catalog for mapping table columns to data elements. If it is a local file use: file:path/to/schema.json. If it is in the Java classpath use: classpath:/schema.json. For more information, refer to the Schema Configuration section.

                                    ptyDbCache

                                    No

                                    false

                                    Improves performance by caching the database schema between queries using the same connection. Any new database objects created after the connection may not be visible.

                                    ptyFunctions

                                    No

                                    Class name of a Java POJO with methods that should be added as SQL user-defined functions. Multiple classes should be separated by commas. For more information, refer to the User-Defined Functions section.

                                    ptyPolicyUser

                                    No

                                    Sets the Protegrity policy username. If not provided, the database user will be used instead. The username can be changed later by executing SET POLICY_USER = '<user>'.

                                    ptyProtectUri

                                    No

                                    Location of the Protegrity security policy. Supported schemes: rps://host:port (policy sync from upstream server), file:/path (local file), s3://bucket/key (AWS S3). If not provided, the value will be loaded from the cloud-protect.properties file in the Java classpath.

                                    ptyStmtCacheSize

                                    No

                                    0

                                    Improves performance by caching the query plan for prepared statements. Changes to the table schema will not invalidate the cache and may cause unexpected behavior. The default value of “0” disables the cache.

                                    1.21 -

                                    Data Types

                                    This section describes the data types that you can use with the JDBC Protector.

                                    Standard Data Types Reference

                                    The JDBC Protector leverages Apache Calcite for supporting the standard SQL data types. For more information and a list of available data types, refer to the Apache Calcite SQL Language reference guide.

                                    Conversion Between Java and JDBC Types

                                    The Protegrity JDBC Protector is flexible in the way it handles conversions between JDBC types and Java types. Any JDBC type can be converted to a String. Calling the ResultSet.getObject() method will return the Java object provided by the database driver. The following table shows the possible ResultSet conversions for each SQL type.

                                    JDBC Types

                                    Java Types

                                    BIGINT

                                    DECIMAL

                                    DOUBLE

                                    FLOAT

                                    INTEGER

                                    NUMERIC

                                    REAL

                                    SMALLINT

                                    TINYINT

                                    double

                                    boolean

                                    byte

                                    float

                                    int

                                    long

                                    short

                                    String

                                    java.math.BigDecimal

                                    BINARY

                                    CHAR

                                    VARBINARY

                                    VARCHAR

                                    byte[]

                                    String

                                    DATE

                                    int

                                    long

                                    String

                                    java.sql.Date

                                    TIME

                                    int

                                    long

                                    String

                                    java.sql.Time

                                    TIMESTAMP

                                    long

                                    String

                                    java.sql.Date

                                    java.sql.Time

                                    java.sql.Timestamp

                                    ARRAY

                                    java.sql.Array

                                    STRUCT

                                    java.sql.Struct

                                    1.22 -

                                    Conversion Between Java and JDBC Types

                                    The Protegrity JDBC Protector is flexible in the way it handles conversions between JDBC types and Java types. Any JDBC type can be converted to a String. Calling the ResultSet.getObject() method will return the Java object provided by the database driver. The following table shows the possible ResultSet conversions for each SQL type.

                                    JDBC Types

                                    Java Types

                                    BIGINT

                                    DECIMAL

                                    DOUBLE

                                    FLOAT

                                    INTEGER

                                    NUMERIC

                                    REAL

                                    SMALLINT

                                    TINYINT

                                    double

                                    boolean

                                    byte

                                    float

                                    int

                                    long

                                    short

                                    String

                                    java.math.BigDecimal

                                    BINARY

                                    CHAR

                                    VARBINARY

                                    VARCHAR

                                    byte[]

                                    String

                                    DATE

                                    int

                                    long

                                    String

                                    java.sql.Date

                                    TIME

                                    int

                                    long

                                    String

                                    java.sql.Time

                                    TIMESTAMP

                                    long

                                    String

                                    java.sql.Date

                                    java.sql.Time

                                    java.sql.Timestamp

                                    ARRAY

                                    java.sql.Array

                                    STRUCT

                                    java.sql.Struct

                                    1.23 -

                                    Standard Data Types Reference

                                    The JDBC Protector leverages Apache Calcite for supporting the standard SQL data types. For more information and a list of available data types, refer to the Apache Calcite SQL Language reference guide.

                                    1.24 -

                                    Standard Functions and Operators Reference

                                    The JDBC Protector leverages Apache Calcite to provide common functions and operators for use in your SQL statements. For more information and a list of available functions and operators, refer to the Apache Calcite SQL Language reference guide.

                                    The following SQL functions are provided in addition to those provided by Apache Calcite:

                                    Database ProviderFunctionNotes
                                    PostgreSQLage(timestamp, timestamp)Requires a ‘FROM’ clause and does not support protected columns. Example: SELECT age(CURRENT_DATE, DATE ‘2023-01-01’) FROM ’table-name’.
                                    PostgreSQLdate_add( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_add(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                                    PostgreSQLdate_subtract( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_subtract(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                                    PostgreSQLclock_timestamp()When used with a protected column, the timezone will be stripped and may throw an exception.
                                    PostgreSQLcurrval( char )
                                    PostgreSQLlastval()
                                    PostgreSQLnextval( char )
                                    PostgreSQLsetval( char, bigint [, boolean] )
                                    PostgreSQLto_number( char, char )When used with a protected column, the timezone will be stripped and may throw an exception.
                                    PostgreSQLxml( char )Throws an exception when used with a protected column.
                                    PostgreSQLxmltable(...)For additional info see PostgreSQL XMLTABLE function documentation. Known Limitations: 1) XMLTABLE does not support PASSING clause with a sub-query, e.g. ‘PASSING (SELECT col-name FROM table-name)’ 2) XMLTABLE does not support TEXT data type, use VARCHAR(n) instead, e.g. instead of ‘COLUMNS col-name TEXT’ use ‘COLUMNS col-name VARCHAR(100)’

                                    1.25 -

                                    Functions and Operators

                                    This section describes the SQL functions and operators that you can use with the JDBC Protector. Additionally, refer to the documentation for your database provider. Functions and operators must be supported by both the JDBC Protector and your database provider to use them in your SQL statements.

                                    Standard Functions and Operators Reference

                                    The JDBC Protector leverages Apache Calcite to provide common functions and operators for use in your SQL statements. For more information and a list of available functions and operators, refer to the Apache Calcite SQL Language reference guide.

                                    The following SQL functions are provided in addition to those provided by Apache Calcite:

                                    Database ProviderFunctionNotes
                                    PostgreSQLage(timestamp, timestamp)Requires a ‘FROM’ clause and does not support protected columns. Example: SELECT age(CURRENT_DATE, DATE ‘2023-01-01’) FROM ’table-name’.
                                    PostgreSQLdate_add( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_add(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                                    PostgreSQLdate_subtract( timestamp with time zone, interval [, text ] )Requires a ‘FROM’ clause and does not support protected columns. Use Apache Calcite interval definition syntax. Example: SELECT date_subtract(DATE ‘2023-01-01’, INTERVAL 60 DAYS) FROM ’table-name’.
                                    PostgreSQLclock_timestamp()When used with a protected column, the timezone will be stripped and may throw an exception.
                                    PostgreSQLcurrval( char )
                                    PostgreSQLlastval()
                                    PostgreSQLnextval( char )
                                    PostgreSQLsetval( char, bigint [, boolean] )
                                    PostgreSQLto_number( char, char )When used with a protected column, the timezone will be stripped and may throw an exception.
                                    PostgreSQLxml( char )Throws an exception when used with a protected column.
                                    PostgreSQLxmltable(...)For additional info see PostgreSQL XMLTABLE function documentation. Known Limitations: 1) XMLTABLE does not support PASSING clause with a sub-query, e.g. ‘PASSING (SELECT col-name FROM table-name)’ 2) XMLTABLE does not support TEXT data type, use VARCHAR(n) instead, e.g. instead of ‘COLUMNS col-name TEXT’ use ‘COLUMNS col-name VARCHAR(100)’

                                    Protegrity Functions

                                    The JDBC Protector provides SQL functions for controlling when the data protection operations occur. This can be used in combination with other SQL functions to, for example, encode protected data before it is stored in the database. When the JDBC Protector encounters one of the functions below in a SQL query, it runs the input expression locally and applies the data protection operation to the result.

                                    pty_protect

                                    Protects values using the given data element.

                                    PTY_PROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to protect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Protected values.

                                    • Exception

                                      If the user does not have protect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_protect('deTokName', column) from table
                                      
                                      select "pty_protect"('deTokName', column) from table
                                      

                                    pty_unprotect

                                    Unprotects values using the given data element.

                                    PTY_UNPROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to unprotect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Unprotected value.

                                    • Exception

                                      If the user does not have unprotect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_unprotect('deTokName', column) from table
                                      
                                      select "pty_unprotect"('deTokName', column) from table
                                      

                                    User-Defined Functions

                                    A user-defined function (UDF) is a SQL function that invokes a Java class to transform data. It can be used in combination with Protegrity Functions to modify how the data protection is applied.

                                    A list of Java class names providing UDFs can be provided as the ptyFunctions property when opening a JDBC connection. The Java classes should be POJOs with one or more public static methods. These methods will be made available as a SQL function with the same name as the method.

                                    The example below executes a SQL function using a UDF defined in the MyPlusFunction class. If this class is added to the com.example package, then the ptyFunctions connection property should be set to com.example.MyPlusFunction.

                                    public class MyPlusFunction {
                                        public static void int MY_PLUS(int left, int right) {
                                            return left + right;
                                        }
                                    }
                                    
                                    SELECT MY_PLUS(1, 2)
                                    

                                    For more information about which Java types are used for each SQL type, refer to the Conversion Between Java and JDBC Types section.

                                    1.26 -

                                    pty_protect

                                    Protects values using the given data element.

                                    PTY_PROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to protect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Protected values.

                                    • Exception

                                      If the user does not have protect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_protect('deTokName', column) from table
                                      
                                      select "pty_protect"('deTokName', column) from table
                                      

                                    1.27 -

                                    Protegrity Functions

                                    The JDBC Protector provides SQL functions for controlling when the data protection operations occur. This can be used in combination with other SQL functions to, for example, encode protected data before it is stored in the database. When the JDBC Protector encounters one of the functions below in a SQL query, it runs the input expression locally and applies the data protection operation to the result.

                                    pty_protect

                                    Protects values using the given data element.

                                    PTY_PROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to protect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Protected values.

                                    • Exception

                                      If the user does not have protect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_protect('deTokName', column) from table
                                      
                                      select "pty_protect"('deTokName', column) from table
                                      

                                    pty_unprotect

                                    Unprotects values using the given data element.

                                    PTY_UNPROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to unprotect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Unprotected value.

                                    • Exception

                                      If the user does not have unprotect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_unprotect('deTokName', column) from table
                                      
                                      select "pty_unprotect"('deTokName', column) from table
                                      

                                    1.28 -

                                    pty_unprotect

                                    Unprotects values using the given data element.

                                    PTY_UNPROTECT(dataElement, values)

                                    • Parameters

                                      NameTypeDescription
                                      dataElementVARCHARName of the data element.
                                      valuesAnyData to unprotect. For more information on supported data types, see Tokenization Types.
                                    • Returns

                                      Unprotected value.

                                    • Exception

                                      If the user does not have unprotect access rights in the policy or the input format is not supported, the UDF terminates with an error message.

                                    • Example

                                      select pty_unprotect('deTokName', column) from table
                                      
                                      select "pty_unprotect"('deTokName', column) from table
                                      

                                    1.29 -

                                    User-Defined Functions

                                    A user-defined function (UDF) is a SQL function that invokes a Java class to transform data. It can be used in combination with Protegrity Functions to modify how the data protection is applied.

                                    A list of Java class names providing UDFs can be provided as the ptyFunctions property when opening a JDBC connection. The Java classes should be POJOs with one or more public static methods. These methods will be made available as a SQL function with the same name as the method.

                                    The example below executes a SQL function using a UDF defined in the MyPlusFunction class. If this class is added to the com.example package, then the ptyFunctions connection property should be set to com.example.MyPlusFunction.

                                    public class MyPlusFunction {
                                        public static void int MY_PLUS(int left, int right) {
                                            return left + right;
                                        }
                                    }
                                    
                                    SELECT MY_PLUS(1, 2)
                                    

                                    For more information about which Java types are used for each SQL type, refer to the Conversion Between Java and JDBC Types section.

                                    1.30 -

                                    The JDBC Protector driver supports the Java Service Provider mechanism and will be automatically detected by the DriverManager facility or a DataSource implementation. The class that implements java.sql.Driver is com.protegrity.jdbc.Driver. JDBC URLs should begin with jdbc:iap: in order to be recognized by the driver.

                                    For example, if your current database connection URL is:

                                    jdbc:mysql://localhost:3306/example
                                    

                                    Then to use the JDBC Protector it should be modified to:

                                    jdbc:iap:mysql://localhost:3306/example
                                    

                                    A basic implementation of a javax.sql.DataSource connection factory is provided by com.protegrity.jdbc.PtyDataSource.

                                    1.31 -

                                    Encryption Algorithms

                                    Encryption is the conversion of data into a ciphertext using an algorithmic scheme. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                                    Encryption Algorithm

                                    All Databases

                                    3DES

                                    AES-128

                                    AES-256

                                    CUSP 3DES

                                    CUSP AES-128

                                    CUPS AES-256

                                    VARBINARY

                                    DTP2-AES-128

                                    DTP2-AES-256

                                    DTP2-3DES

                                    DTP2-SHA1

                                    Not supported

                                    1.32 -

                                    Hashing

                                    The JDBC Protector does not currently support the Protegrity hashing protection methods.

                                    1.33 -

                                    Masking

                                    For situations where data output restrictions must be applied for users, the Masking method can be used. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                                    Protection Method

                                    Database

                                    Oracle

                                    Other Database

                                    Masking

                                    CHAR

                                    INTEGER

                                    VARCHAR2

                                    CHAR

                                    INTEGER

                                    VARCHAR

                                    1.34 -

                                    No Encryption

                                    The No Encryption protection method when applied lets sensitive data be stored in the clear, but either monitors or masks its usage through a data security policy. The following table illustrates the supported data types and supplements the Protegrity Protection Methods Reference Guide.

                                    Protection Method

                                    Database

                                    Oracle

                                    Other Database

                                    No Encryption

                                    CHAR

                                    INTEGER

                                    VARCHAR2

                                    CHAR

                                    INTEGER

                                    VARCHAR

                                    1.35 -

                                    CALL

                                    
                                    CALL identifier '(' [ param [ , param ]* ] ')'
                                    

                                    1.36 -

                                    COMMIT

                                    
                                    COMMIT [ WORK ] [ AND { CHAIN | NO CHAIN ] ]
                                    

                                    1.37 -

                                    DELETE

                                    
                                    DELETE FROM [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                                    [ WHERE booleanExpression ]
                                    

                                    1.38 -

                                    INSERT/UPSERT

                                    
                                    { INSERT | UPSERT } INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    [ '(' column [, column ]* ')' ]
                                    { [values](jdbc_dev_calcite_ref_statementSelectValues.md) | [query](jdbc_dev_calcite_ref_statementSelect.md) }
                                    [ ON CONFLICT DO
                                        {
                                            NOTHING
                                        |   UPDATE SET identifier '=' expression [, identifier '=' expression ]*
                                        }
                                    ]
                                    

                                    1.39 -

                                    MERGE

                                    
                                    MERGE INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                                    USING [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    ON booleanExpression
                                    [ WHEN MATCHED THEN UPDATE SET identifier '=' expression [, identifier '=' expression ]* ]
                                    [ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
                                    

                                    1.40 -

                                    RESET

                                    
                                    [ ALTER { SYSTEM | SESSION } ] RESET { identifier | ALL }
                                    

                                    1.41 -

                                    ROLLBACK

                                    
                                    ROLLBACK [ WORK ] [ AND { CHAIN | NO CHAIN ] ] [ TO SAVEPOINT identifier ]
                                    

                                    1.42 -

                                    SAVEPOINT

                                    
                                    [ RELEASE ] SAVEPOINT identifier
                                    

                                    1.43 -

                                    groupItem

                                    
                                        expression
                                    |   '(' ')'
                                    |   '(' expression [, expression ]* ')'
                                    |   CUBE '(' expression [, expression ]* ')'
                                    |   ROLLUP '(' expression [, expression ]* ')'
                                    |   GROUPING SETS '(' groupItem [, groupItem ]* ')'
                                    

                                    1.44 -

                                    hintComment

                                    
                                    hintComment:
                                            '/*+' { hintName | hintName '(' hintOptions ')' } '*/'
                                    
                                    
                                    hintOptions:
                                            hintKVOption [, hintKVOption ]*
                                        |   optionName [, optionName ]*
                                        |   hintOptionValue [, hintOptionValue ]*
                                    
                                    hintKVOption:
                                            optionName '=' stringLiteral
                                        |   stringLiteral '=' stringLiteral
                                    
                                    hintOptionValue:
                                            stringLiteral | numericLiteral
                                    

                                    1.45 -

                                    matchRecognize

                                    JDBC Protector uses Apache Calcite for SQL statement parsing. MATCH_RECOGNIZE is a SQL extension for recognizing sequences of events in complex event processing (CEP). It is experimental in Apache Calcite, and may not be fully implemented yet.

                                    
                                    matchRecognize:
                                            MATCH_RECOGNIZE
                                            '('
                                            [ PARTITION BY expression [, expression ]* ]
                                            [ ORDER BY order ]
                                            [ MEASURES expression AS alias [, expression AS alias ]* ]
                                            [ ONE ROW PER MATCH | ALL ROWS PER MATCH ]
                                            [ AFTER MATCH skip ]
                                            PATTERN '(' [ '^' ] pattern [ '$' ] ')'
                                            [ WITHIN  intervalLiteral ]
                                            [ SUBSET  subsetItem [, subsetItem ]* ]
                                            DEFINE  variable AS condition [, variable AS condition ]*
                                            ')'
                                    
                                    order:
                                            ORDER OF tableIdentifier
                                        |   [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) [, [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) ]*
                                    
                                    skip:
                                            SKIP TO NEXT ROW
                                        |   SKIP PAST LAST ROW
                                        |   SKIP TO FIRST identifier
                                        |   SKIP TO [ LAST ] identifier
                                    
                                    pattern:
                                            patternTerm [ '|' patternTerm ]*
                                    
                                    patternTerm:
                                            patternFactor [ patternFactor ]*
                                    
                                    patternFactor:
                                            patternPrimary [ patternQuantifier ]
                                    
                                    patternPrimary:
                                            identifier
                                        | 	'(' pattern ')'
                                        | 	'{-' pattern '-}'
                                        | 	PERMUTE '(' pattern [ , pattern ]* ')'
                                    
                                    patternQuantifier:
                                            '*'
                                        |   '+'
                                        |   '{' minRepeatNumericLiteral [ , maxRepeatNumericLiteral ] '}'
                                        |   '{' repeatNumericLiteral '}'
                                        |   '{-' pattern '-}'
                                    
                                    
                                    intervalLiteral:
                                            INTERVAL [ '-' | '+' ] stringLiteral timeUnit [ TO timeUnit ]
                                    
                                    subsetItem:
                                            identifier '=(' expression [ , expression ]* ')'
                                    

                                    1.46 -

                                    orderItem

                                    
                                    expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
                                    

                                    1.47 -

                                    pivot

                                    
                                    pivot:
                                            PIVOT '('
                                            pivotAgg [, pivotAgg ]*
                                            FOR { column |  '(' column [, column ]* ')'
                                            IN '(' pivotExpression [, pivotExpression ]* ')'
                                            ')'
                                    
                                    pivotAgg:
                                            agg '(' [ ALL | DISTINCT ] value [, value ]* ')'
                                            [ [ AS ] alias ]
                                    
                                    pivotExpression:
                                            { expression |  '(' expression [, expression ]* ')' } [ [ AS ] alias ]
                                    

                                    1.48 -

                                    projectItem

                                    
                                    expression [ [ AS ] columnAlias ] | tableAlias . *
                                    

                                    1.49 -

                                    SELECT

                                    [WITH [ RECURSIVE ] withItem [ , withItem ]* query]
                                    SELECT [ hintComment ] [ STREAM ]
                                    [ SKIP UnsignedNumericLiteralOrParam ]
                                    [
                                      { FIRST | LIMIT } UnsignedNumericLiteralOrParam
                                      | TOP { '(' UnsignedNumericLiteralOrParam ')' | UnsignedNumericLiteralOrParam }
                                    ]
                                    [ ALL | DISTINCT ]
                                    { * | projectItem [, projectItem ]* }
                                    [ FROM tableExpression ]
                                    [ WHERE booleanExpression ]
                                    [ GROUP BY [ ALL | DISTINCT ] { groupItem [, groupItem ]* } ]
                                    [ HAVING booleanExpression ]
                                    [ WINDOW windowName AS windowSpec [, windowName AS windowSpec ]* ]
                                    [ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] query ]
                                    [ QUALIFY booleanExpression ]
                                    [ ORDER BY orderItem [, orderItem ]* ]
                                    [ LIMIT [ start, ] { count | ALL } ]
                                    [ OFFSET start { ROW | ROWS } ]
                                    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
                                    [ FOR { SHARE | UPDATE } [ { NOWAIT | SKIP LOCKED } ] ]
                                    

                                    groupItem

                                    
                                        expression
                                    |   '(' ')'
                                    |   '(' expression [, expression ]* ')'
                                    |   CUBE '(' expression [, expression ]* ')'
                                    |   ROLLUP '(' expression [, expression ]* ')'
                                    |   GROUPING SETS '(' groupItem [, groupItem ]* ')'
                                    

                                    hintComment

                                    
                                    hintComment:
                                            '/*+' { hintName | hintName '(' hintOptions ')' } '*/'
                                    
                                    
                                    hintOptions:
                                            hintKVOption [, hintKVOption ]*
                                        |   optionName [, optionName ]*
                                        |   hintOptionValue [, hintOptionValue ]*
                                    
                                    hintKVOption:
                                            optionName '=' stringLiteral
                                        |   stringLiteral '=' stringLiteral
                                    
                                    hintOptionValue:
                                            stringLiteral | numericLiteral
                                    

                                    matchRecognize

                                    JDBC Protector uses Apache Calcite for SQL statement parsing. MATCH_RECOGNIZE is a SQL extension for recognizing sequences of events in complex event processing (CEP). It is experimental in Apache Calcite, and may not be fully implemented yet.

                                    
                                    matchRecognize:
                                            MATCH_RECOGNIZE
                                            '('
                                            [ PARTITION BY expression [, expression ]* ]
                                            [ ORDER BY order ]
                                            [ MEASURES expression AS alias [, expression AS alias ]* ]
                                            [ ONE ROW PER MATCH | ALL ROWS PER MATCH ]
                                            [ AFTER MATCH skip ]
                                            PATTERN '(' [ '^' ] pattern [ '$' ] ')'
                                            [ WITHIN  intervalLiteral ]
                                            [ SUBSET  subsetItem [, subsetItem ]* ]
                                            DEFINE  variable AS condition [, variable AS condition ]*
                                            ')'
                                    
                                    order:
                                            ORDER OF tableIdentifier
                                        |   [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) [, [orderItem](jdbc_dev_calcite_ref_statementSelectOrder.md) ]*
                                    
                                    skip:
                                            SKIP TO NEXT ROW
                                        |   SKIP PAST LAST ROW
                                        |   SKIP TO FIRST identifier
                                        |   SKIP TO [ LAST ] identifier
                                    
                                    pattern:
                                            patternTerm [ '|' patternTerm ]*
                                    
                                    patternTerm:
                                            patternFactor [ patternFactor ]*
                                    
                                    patternFactor:
                                            patternPrimary [ patternQuantifier ]
                                    
                                    patternPrimary:
                                            identifier
                                        | 	'(' pattern ')'
                                        | 	'{-' pattern '-}'
                                        | 	PERMUTE '(' pattern [ , pattern ]* ')'
                                    
                                    patternQuantifier:
                                            '*'
                                        |   '+'
                                        |   '{' minRepeatNumericLiteral [ , maxRepeatNumericLiteral ] '}'
                                        |   '{' repeatNumericLiteral '}'
                                        |   '{-' pattern '-}'
                                    
                                    
                                    intervalLiteral:
                                            INTERVAL [ '-' | '+' ] stringLiteral timeUnit [ TO timeUnit ]
                                    
                                    subsetItem:
                                            identifier '=(' expression [ , expression ]* ')'
                                    

                                    orderItem

                                    
                                    expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
                                    

                                    pivot

                                    
                                    pivot:
                                            PIVOT '('
                                            pivotAgg [, pivotAgg ]*
                                            FOR { column |  '(' column [, column ]* ')'
                                            IN '(' pivotExpression [, pivotExpression ]* ')'
                                            ')'
                                    
                                    pivotAgg:
                                            agg '(' [ ALL | DISTINCT ] value [, value ]* ')'
                                            [ [ AS ] alias ]
                                    
                                    pivotExpression:
                                            { expression |  '(' expression [, expression ]* ')' } [ [ AS ] alias ]
                                    

                                    projectItem

                                    
                                    expression [ [ AS ] columnAlias ] | tableAlias . *
                                    

                                    tableExpression

                                    
                                    tableExpression:
                                            tableReference [, tableReference ]*
                                        |   tableExpression
                                            [ NATURAL ] [ { LEFT | RIGHT | FULL } [ OUTER ] ]
                                            JOIN tableExpression
                                            [ joinCondition ]
                                        |   tableExpression CROSS JOIN tableExpression
                                        |   tableExpression [ CROSS | OUTER ] APPLY tableExpression
                                    
                                    tableReference:
                                            tablePrimary
                                            [ FOR SYSTEM_TIME AS OF expression ]
                                            [ [pivot](jdbc_dev_calcite_ref_statementSelectPivot.md) ]
                                            [ [unpivot](jdbc_dev_calcite_ref_statementSelectUnpivot.md) ]
                                            [ [matchRecognize](jdbc_dev_calcite_ref_statementSelectMatchRecognize.md) ]
                                            [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
                                    
                                    tablePrimary:
                                            [ [ catalogName . ] schemaName . ] tableName
                                            '(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
                                        |   tablePrimary [ [hintComment](jdbc_dev_calcite_ref_statementSelectHintComment.md) ] [ EXTEND ] columnDeclarations
                                        |   [ LATERAL ] '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                                        |   UNNEST '(' expression ')' [ WITH ORDINALITY ]
                                        |   [ LATERAL ] TABLE
                                            '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
                                    
                                    joinCondition:
                                            ON booleanExpression
                                        |   USING '(' column [, column ]* ')'
                                    
                                    columnDeclarations:
                                            '(' column type [ NOT NULL ] [, column type [ NOT NULL ] ]* ')'
                                    

                                    unpivot

                                    
                                    unpivot:
                                            UNPIVOT [ INCLUDING NULLS | EXCLUDING NULLS ] '('
                                            { column | '(' column [, column ]* ')' }
                                            FOR { column | '(' column [, column ]* ')' }
                                            IN '(' unpivotValue [, unpivotValue ]* ')'
                                            ')'
                                    
                                    unpivotValue:
                                            column [ AS literal ]
                                        |   '(' column [, column ]* ')' [ AS '(' literal [, literal ]* ')' ]
                                    

                                    values

                                    
                                    values:
                                            { VALUES | VALUE } rowConstructor [, rowConstructor ]*
                                    
                                    rowConstructor:
                                            { '(' ROW rowSpec ')' | ROW } rowSpec | expression
                                    
                                    rowSpec:
                                            '(' { { values | [query](jdbc_dev_calcite_ref_statementSelect.md) } | DEFAULT } [ , { expression | DEFAULT } ]* ')'
                                    

                                    windowSpec

                                    
                                    '('
                                    [ windowName ]
                                    [ ORDER BY orderItem [, orderItem ]* ]
                                    [ PARTITION BY expression [, expression ]* ]
                                    [
                                        RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
                                    |   ROWS numericExpression { PRECEDING | FOLLOWING }
                                    ]
                                    ')'
                                    

                                    withItem

                                    
                                    name
                                    [ '(' column [, column ]* ')' ]
                                    AS '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                                    

                                    1.50 -

                                    tableExpression

                                    
                                    tableExpression:
                                            tableReference [, tableReference ]*
                                        |   tableExpression
                                            [ NATURAL ] [ { LEFT | RIGHT | FULL } [ OUTER ] ]
                                            JOIN tableExpression
                                            [ joinCondition ]
                                        |   tableExpression CROSS JOIN tableExpression
                                        |   tableExpression [ CROSS | OUTER ] APPLY tableExpression
                                    
                                    tableReference:
                                            tablePrimary
                                            [ FOR SYSTEM_TIME AS OF expression ]
                                            [ [pivot](jdbc_dev_calcite_ref_statementSelectPivot.md) ]
                                            [ [unpivot](jdbc_dev_calcite_ref_statementSelectUnpivot.md) ]
                                            [ [matchRecognize](jdbc_dev_calcite_ref_statementSelectMatchRecognize.md) ]
                                            [ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
                                    
                                    tablePrimary:
                                            [ [ catalogName . ] schemaName . ] tableName
                                            '(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
                                        |   tablePrimary [ [hintComment](jdbc_dev_calcite_ref_statementSelectHintComment.md) ] [ EXTEND ] columnDeclarations
                                        |   [ LATERAL ] '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                                        |   UNNEST '(' expression ')' [ WITH ORDINALITY ]
                                        |   [ LATERAL ] TABLE
                                            '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
                                    
                                    joinCondition:
                                            ON booleanExpression
                                        |   USING '(' column [, column ]* ')'
                                    
                                    columnDeclarations:
                                            '(' column type [ NOT NULL ] [, column type [ NOT NULL ] ]* ')'
                                    

                                    1.51 -

                                    unpivot

                                    
                                    unpivot:
                                            UNPIVOT [ INCLUDING NULLS | EXCLUDING NULLS ] '('
                                            { column | '(' column [, column ]* ')' }
                                            FOR { column | '(' column [, column ]* ')' }
                                            IN '(' unpivotValue [, unpivotValue ]* ')'
                                            ')'
                                    
                                    unpivotValue:
                                            column [ AS literal ]
                                        |   '(' column [, column ]* ')' [ AS '(' literal [, literal ]* ')' ]
                                    

                                    1.52 -

                                    values

                                    
                                    values:
                                            { VALUES | VALUE } rowConstructor [, rowConstructor ]*
                                    
                                    rowConstructor:
                                            { '(' ROW rowSpec ')' | ROW } rowSpec | expression
                                    
                                    rowSpec:
                                            '(' { { values | [query](jdbc_dev_calcite_ref_statementSelect.md) } | DEFAULT } [ , { expression | DEFAULT } ]* ')'
                                    

                                    1.53 -

                                    windowSpec

                                    
                                    '('
                                    [ windowName ]
                                    [ ORDER BY orderItem [, orderItem ]* ]
                                    [ PARTITION BY expression [, expression ]* ]
                                    [
                                        RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
                                    |   ROWS numericExpression { PRECEDING | FOLLOWING }
                                    ]
                                    ')'
                                    

                                    1.54 -

                                    withItem

                                    
                                    name
                                    [ '(' column [, column ]* ')' ]
                                    AS '(' [query](jdbc_dev_calcite_ref_statementSelect.md) ')'
                                    

                                    1.55 -

                                    SET CONSTRAINTS

                                    
                                    SET CONSTRAINTS { ALL | identifier [ , identifier ] } { DEFERRED | IMMEDIATE }
                                    

                                    1.56 -

                                    SET TRANSACTION

                                    
                                    SET [ LOCAL ] TRANSACTION [transactionCharacteristics](jdbc_dev_calcite_ref_statementTransactionCharacteristics.md)
                                    

                                    1.57 -

                                    SET

                                    [ ALTER { SYSTEM | SESSION } ] SET identifier { TO | '=' } { literal | identifier | ON }
                                    

                                    SET CONSTRAINTS

                                    
                                    SET CONSTRAINTS { ALL | identifier [ , identifier ] } { DEFERRED | IMMEDIATE }
                                    

                                    SET TRANSACTION

                                    
                                    SET [ LOCAL ] TRANSACTION [transactionCharacteristics](jdbc_dev_calcite_ref_statementTransactionCharacteristics.md)
                                    

                                    START TRANSACTION

                                    START TRANSACTION transactionCharacteristics
                                    

                                    transactionCharacteristics

                                    transactionCharacteristics:
                                    [ transactionMode [ , transactionMode ]* ]
                                    
                                    transactionMode:
                                    ISOLATION LEVEL transactionLevel
                                    | { READ WRITE | READ ONLY }
                                    | DIAGNOSTICS SIZE UnsignedIntLiteral
                                    
                                    transactionLevel:
                                    READ COMMITTED
                                    | READ UNCOMMITTED
                                    | REPEATABLE READ
                                    | SERIALIZABLE
                                    

                                    UPDATE

                                    
                                    UPDATE [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    SET identifier '=' expression [, identifier '=' expression ]*
                                    [ WHERE booleanExpression ]
                                    

                                    1.58 -

                                    SQL Grammar

                                    This section describes the SQL dialect recognized by the JDBC Protector’s default SQL parser. The default grammar is SQL 2003 standard with some extensions from Oracle, MySQL, PostgreSQL, and SQL Server.

                                    CALL

                                    
                                    CALL identifier '(' [ param [ , param ]* ] ')'
                                    

                                    COMMIT

                                    
                                    COMMIT [ WORK ] [ AND { CHAIN | NO CHAIN ] ]
                                    

                                    DELETE

                                    
                                    DELETE FROM [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                                    [ WHERE booleanExpression ]
                                    

                                    INSERT/UPSERT

                                    
                                    { INSERT | UPSERT } INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    [ '(' column [, column ]* ')' ]
                                    { [values](jdbc_dev_calcite_ref_statementSelectValues.md) | [query](jdbc_dev_calcite_ref_statementSelect.md) }
                                    [ ON CONFLICT DO
                                        {
                                            NOTHING
                                        |   UPDATE SET identifier '=' expression [, identifier '=' expression ]*
                                        }
                                    ]
                                    

                                    MERGE

                                    
                                    MERGE INTO [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md) [ [ AS ] alias ]
                                    USING [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    ON booleanExpression
                                    [ WHEN MATCHED THEN UPDATE SET identifier '=' expression [, identifier '=' expression ]* ]
                                    [ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
                                    

                                    RESET

                                    
                                    [ ALTER { SYSTEM | SESSION } ] RESET { identifier | ALL }
                                    

                                    ROLLBACK

                                    
                                    ROLLBACK [ WORK ] [ AND { CHAIN | NO CHAIN ] ] [ TO SAVEPOINT identifier ]
                                    

                                    SAVEPOINT

                                    
                                    [ RELEASE ] SAVEPOINT identifier
                                    

                                    1.59 -

                                    START TRANSACTION

                                    START TRANSACTION transactionCharacteristics
                                    

                                    transactionCharacteristics

                                    transactionCharacteristics:
                                    [ transactionMode [ , transactionMode ]* ]
                                    
                                    transactionMode:
                                    ISOLATION LEVEL transactionLevel
                                    | { READ WRITE | READ ONLY }
                                    | DIAGNOSTICS SIZE UnsignedIntLiteral
                                    
                                    transactionLevel:
                                    READ COMMITTED
                                    | READ UNCOMMITTED
                                    | REPEATABLE READ
                                    | SERIALIZABLE
                                    

                                    UPDATE

                                    
                                    UPDATE [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    SET identifier '=' expression [, identifier '=' expression ]*
                                    [ WHERE booleanExpression ]
                                    

                                    1.60 -

                                    transactionCharacteristics

                                    
                                    transactionCharacteristics:
                                            [ transactionMode [ , transactionMode ]* ]
                                    
                                    transactionMode:
                                            ISOLATION LEVEL transactionLevel
                                        |   { READ WRITE | READ ONLY }
                                        |   DIAGNOSTICS SIZE UnsignedIntLiteral
                                    
                                    transactionLevel:
                                            READ COMMITTED
                                        |   READ UNCOMMITTED
                                        |   REPEATABLE READ
                                        |   SERIALIZABLE
                                    

                                    Parent topic:START TRANSACTION

                                    1.61 -

                                    transactionCharacteristics

                                    transactionCharacteristics:
                                    [ transactionMode [ , transactionMode ]* ]
                                    
                                    transactionMode:
                                    ISOLATION LEVEL transactionLevel
                                    | { READ WRITE | READ ONLY }
                                    | DIAGNOSTICS SIZE UnsignedIntLiteral
                                    
                                    transactionLevel:
                                    READ COMMITTED
                                    | READ UNCOMMITTED
                                    | REPEATABLE READ
                                    | SERIALIZABLE
                                    

                                    1.62 -

                                    UPDATE

                                    
                                    UPDATE [tablePrimary](jdbc_dev_calcite_ref_statementSelectTableExpression.md)
                                    SET identifier '=' expression [, identifier '=' expression ]*
                                    [ WHERE booleanExpression ]
                                    

                                    1.63 -

                                    Alpha (A-Z)

                                    The Alpha token type tokenizes both uppercase and lowercase letters.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Alpha

                                    Token Type and Format

                                    Lowercase letters ‘a’ through ‘z’

                                    Uppercase letters ‘A’ through ‘Z’

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Alpha token.
                                    Input ValueTokenized ValueComments
                                    131 Summer Street, Bridgewater131 VDYgAK qvMDUn, zAEXmwqWYNQGNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                                    Albert EinsteinSldGzm OOCTzSFoSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                                    1.64 -

                                    Alpha-Numeric (0-9, a-z, A-Z)

                                    The Alpha-Numeric token type tokenizes all alphabetic symbols (both lowercase and uppercase letters), as well as digits from 0 to 9.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Alpha-Numeric

                                    Token Type and Format

                                    Digits 0 through 9

                                    Lowercase letters ‘a’ through ‘z’

                                    Uppercase letters ‘A’ through ‘Z’

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Alpha-Numeric token.
                                    Input ValueTokenized ValueComments
                                    123sQOInput is numeric but tokenized value contains uppercase and lowercase alpha characters.
                                    131 Summer Street, BridgewaterikC ejCxxp kLa2ZZ, 5x8K2IMubcnSpaces and comma are treated as delimiters and not tokenized.
                                    704-BBJjf7-oVYDash is treated as delimiter. The rest of value is tokenized.

                                    1.65 -

                                    Lower ASCII

                                    The Lower ASCII token type is provided to address the handling of spaces in such data types as CHAR and VARCHAR.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Lower ASCII

                                    Token Type and Format

                                    The lower part of the ASCII table:

                                    Hex character codes from 0x21 to 0x7E

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Lower ASCII token.

                                    Input Value

                                    Tokenized Value

                                    Comments

                                    La Scala 05698

                                    :H HnwqP v/Q`>

                                    All characters in the input value (except of spaces) are tokenized.

                                    Ford Mondeo CA-0256TY

                                    M34 567 K-45

                                    j`1$ nRSD<X T]!(~4MWF

                                    l:f cF+ R?V{

                                    All characters in the input value (except of spaces) are tokenized.

                                    **

                                    1.66 -

                                    Credit Card

                                    The Credit Card token type helps maintain transparency, and also provides a way to clearly distinguish a token from the real value, which is a recommendation of the PCI DSS.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Credit Card

                                    Token Type and Format

                                    Digits 0 through 9

                                    (no separators are allowed as input)

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    1.67 -

                                    Date (YYYY-MM-DD, DD/MM/YYYY, MM.DD.YYYY)

                                    The Date token type protects dates in big endian, little endian, or middle endian form.

                                    The following formats are supported:

                                    • YYYY<delim>MM<delim>DD
                                    • DD<delim>MM<delim>YYYY
                                    • MM<delim>DD<delim>YYYY

                                    where <delim> is one of the allowed separators: . (dot), / (slash), or - (dash).

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Date

                                    Token Type and Format

                                    Date in big endian form, starting with the year (YYYY-MM-DD)

                                    Date in little endian form, starting with the day (DD/MM/YYYY)

                                    Date in middle endian form, starting with the month (MM.DD.YYYY)

                                    The following separators are supported: . (dot), / (slash), - (dash)

                                    Supported input data types *1

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    Supported range of input dates

                                    From “0600-01-01” to “3337-11-27”

                                    Date token types are not fully validated for input value as valid date. For example, a day value greater than 31 and month value greater than 12 results in an error, but the date input 2011-02-30 does not. However, the detokenized value would be 2011-03-02, which is not the initial value.

                                    The following table shows examples of the way in which a value will be tokenized with the Date token.

                                    Input Value

                                    Tokenized Value

                                    Comments

                                    2012-02-29

                                    2012/02/29

                                    2012.02.29

                                    2150-02-20

                                    2150/02/20

                                    2150.02.20

                                    All three separators are successfully accepted. They are treated as delimiters not impacting tokenized value.

                                    31/01/0600

                                    08/05/2215

                                    Date in the past is tokenized.

                                    10.30.3337

                                    09.05.2042

                                    Date in the future is tokenized.

                                    • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                      Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                                      The following points are applicable for the tokenization and de-tokenization of the cutover dates of the Proleptic Gregorian Calendar:

                                      • The tokenization of the date values in the cutover date range of the Proleptic Gregorian Calendar results in an ‘Invalid Input’ error.
                                      • During tokenization, an internal validation is performed to check whether the value is tokenized to the cutover date. If it is a cutover date, then the Year part (1582) of the tokenized value is converted to 3338 and then returned. During de-tokenization, an internal check is performed to validate whether the Year is 3338. If the Year is 3338, then it is internally converted to 1582.

                                    1.68 -

                                    Datetime (YYYY-MM-DD HH:MM:SS)

                                    The Datetime token type was introduced in response to requirements to allow specific date parts to remain in the clear and for date tokens to be distinguishable from real dates. This token type will also allow for time to be tokenized (HH:MM:SS) with the exception of milliseconds (MMM).

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Datetime

                                    Token Type and Format

                                    Datetime in the following formats:

                                    YYYY-MM-DD HH:MM:SS.MMM

                                    YYYY-MM-DDTHH:MM:SS.MMM

                                    YYYY-MM-DD HH:MM:SS

                                    YYYY-MM-DDTHH:MM:SS

                                    YYYY-MM-DD

                                    From “0600-01-01” to “3337-11-27”, alphabetic digits 0-9, only specific delimiters

                                    Input separators (delimiter) between date, month and year

                                    . (dot), / (slash), or - (dash)

                                    Input separators (delimiter) between hours, minutes and seconds

                                    : (colon) only

                                    Input separator (delimiter) between date and hour

                                    " " (space) or “T” (the letter T)

                                    Input separator (delimiter) between seconds and milliseconds

                                    . (dot) or , (comma)

                                    Supported input data types *1 *2

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Datetime token.

                                    Input ValueTokenized ValueComments
                                    2009.04.12 12:23:34.3331595.06.19 14:31:51.333YYYY-MM-DD HH:MM:SS.MMM. Milliseconds value is left in the clear.
                                    2009.04.12 12:23:341595.06.19 14:31:51YYYY-MM-DD HH:MM:SS with space separator between day and hour.
                                    2234.10.12T12:23:232755.08.04T22:33:43YYYY-MM-DDTHH:MM:SS with T separator between day and hour values.
                                    • Date Tokenization for Cutover Dates of the Proleptic Gregorian Calendar

                                      Java does not accept the cutover dates of the Proleptic Gregorian Calendar. The cutover dates of the Proleptic Gregorian Calendar fall in the interval 1582-10-05 to 1582-10-14. These dates are converted to 1582-10-15. Conversion occurs by adding ten days to the source date. Due to this conversion, data loss occurs as the system is not capable to return the actual date value after the de-tokenization.

                                    1.69 -

                                    Decimal

                                    The Decimal token type tokenizes numbers which may have a precision and scale. The resulting token does not contain any zeros which makes it suitable to store in a decimal data type in a database. Any sign or decimal point delimiter are stripped from the input value before tokenization and put back after tokenization.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Decimal

                                    Token Type and Format

                                    Digits 0 through 9 in input value, 1 thorough 9 in output value

                                    The sign (+ or -) and decimal point (. or ,) separator

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Decimal token.
                                    Input ValueTokenized ValueComments
                                    519.02268.68Input value has (.) dot separator.
                                    -0.333807-9.893967Input value has sign and (.) dot separator.
                                    +,461+,918Input value has sign and (,) comma separator.

                                    1.70 -

                                    Email

                                    Email token type allows tokenization of an email address. Email token keeps the domain name along with all characters after the “@” sign, and the “@” sign itself in the clear. The local part (i.e. the part before “@”) gets tokenized.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Email

                                    Token Type and Format

                                    Alphabetic and numeric only. The rest characters will be treated as delimiters.

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    1.71 -

                                    Integer (0-9)

                                    The Integer token type tokenizes 2, 4, or 8 byte sized integers.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Integer

                                    Token Type and Format

                                    2, 4, or 8 byte sized integers

                                    Supported input data types

                                    All Databases

                                    INTEGER

                                    The following table shows examples of the way in which a value will be tokenized with the Integer token.
                                    Input ValueTokenized ValueComments
                                    31465For 2 bytes, the values can range from -32768 to 32767.
                                    3782939681For 4 bytes, the values can range from -2147483648 to 2147483647.
                                    37268379031142372719For 8 bytes, the value range can range from -9223372036854775808 to 9223372036854775807.

                                    1.72 -

                                    Numeric (0-9)

                                    The Numeric token type tokenizes digits from 0 to 9.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Numeric

                                    Token Type and Format

                                    Digits 0 through 9

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Numeric token.
                                    Input ValueTokenized ValueComments
                                    -7634.119-4306.861Decimal point and sign are treated as delimiters and not tokenized.
                                    12+38=5098+24=62Arithmetic signs are treated as delimiters and not tokenized.
                                    704-BBJ134-BBJAlpha characters are treated as delimiters and not tokenized.

                                    1.73 -

                                    Printable

                                    The Printable token type tokenizes ASCII printable characters from the ISO 8859-15 alphabet, which include letters, digits, punctuation marks, and miscellaneous symbols.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Alpha

                                    Token Type and Format

                                    ASCII printable characters, which include letters, digits, punctuation marks, and miscellaneous symbols

                                    Hex character codes from 0x20 to 0x7E and from 0xA0 to 0xFF

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Printable token.

                                    Input Value

                                    Tokenized Value

                                    Comments

                                    La Scala 05698

                                    F|ZpÙç|Ôä%s^¦4

                                    All characters in the input value (including spaces) are tokenized.

                                    Ford Mondeo CA-0256TY

                                    M34 567 K-45

                                    §)%ß#)ðYjt{¬ÓÊEµV²ù²

                                    All characters in the input value (including spaces) are tokenized.

                                    1.74 -

                                    Upper-case Alpha (A-Z)

                                    The Upper-case Alpha token type tokenizes all alphabetic symbols as uppercase. After de-tokenization, all alphabetic symbols are returned as uppercase. This means that initial and detokenized values would not match if the input contains lowercase letters.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Upper-case Alpha

                                    Token Type and Format

                                    Uppercase letters ‘A’ through ‘Z’

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Upper-case Alpha token.
                                    Input ValueTokenized ValueComments
                                    abcOIMLowercase characters in the input are converted to uppercase in output. De-tokenization will return ‘ABC’.
                                    131 Summer Street, Bridgewater131 ZBXDPW GFYTZP, CRTTPXPLYGCUNumeric characters, spaces and comma are treated as delimiters and not tokenized. Output value is longer than initial value.
                                    Albert EinsteinAOALXO POHLFHMUSpace is treated as delimiters and not tokenized. Output value is the same length as initial value.

                                    1.75 -

                                    Upper Alpha-Numeric (0-9, A-Z)

                                    The Upper Alpha-Numeric token type tokenizes uppercase letters A through Z and digits 0 to 9.

                                    Tokenization Type Properties

                                    Settings

                                    Name

                                    Upper Alpha-Numeric

                                    Token Type and Format

                                    Digits 0 through 9

                                    Uppercase letters ‘A’ through ‘Z’

                                    Supported input data types

                                    Oracle

                                    Other Databases

                                    CHAR

                                    VARCHAR2

                                    CHAR

                                    VARCHAR

                                    The following table shows examples of the way in which a value will be tokenized with the Upper Alpha-Numeric token.
                                    Input ValueTokenized ValueComments
                                    123STDInput is numeric but tokenized value contains uppercase alpha characters.
                                    131 Summer Street, Bridgewater8C9 CSD5PS 1X5ZJH, 231JHXW8CVFSpaces and comma are treated as delimiters and not tokenized. Lowercase characters in the input are converted to uppercase in output. De-tokenization will return all alpha characters in upper case.

                                    1.76 -

                                    JDBC API

                                    The following JDBC API methods are not implemented and will throw an exception. The application can bypass the JDBC Protector and invoke these methods from the underlying native driver’s connection; however, this will not utilize the JDBC Protector’s transparent protection capabilities.

                                    • Connection#abort(Executor)
                                    • Connection#createBlob()
                                    • Connection#createClob()
                                    • Connection#createNClob()
                                    • Connection#createSQLXML()
                                    • Connection#createStruct(String, Object[])
                                    • ResultSet methods that modify the data
                                    • ResultSet methods that modify the cursor
                                    • ResultSet#isLast()
                                    • Statement#getGeneratedKeys()

                                    1.77 -

                                    The JDBC Protector aims to support many database types and versions, and provide compatibility with other Java APIs and libraries. This section lists the known incompatibilities and limitations. Full compatibility with every database and Java library cannot be guaranteed, and additional limitations may not be listed here.

                                    The protector has the following limitations:

                                    • CLOUDS-1250: When a query ends with a semicolon, an exception is thrown stating “parse failed: Encountered “;””.

                                      • Workaround: Remove the semicolon at the end of the query.
                                    • CLOUDS-1324: When inserting a null value into a decimal column, an exception can be thrown stating “Unable to implement JdbcToEnumerableConverter”.

                                      • Workaround: Add a non-null value for the preceding column in the insert query.
                                    • CLOUDS-2101: The Protegrity reprotect operation is not currently supported. Please submit an RFE if you require this feature in the JDBC Protector.

                                      • Workaround: Perform an unprotect operation followed by a protect operation.
                                    • CLOUDS-2750: A pty_protect() call with an integer data type will cause the query to fail when the mask character is a non-numeric character such as an asterisk, hash, or hyphen.

                                      • Workaround: Either cast the integer value to a char type, or change the mask character to a number.
                                    • CLOUDS-3057: The SQL functions CURRENT_ROLE, CURRENT_USER, SESSION_USER, SYSTEM_USER, and USER only work when connecting to a PostgreSQL database.

                                      • Workaround: Often these values can be obtained from other sources or replaced with a literal value.
                                    • CLOUDS-3301: The QUARTER and WEEK intervals return incorrect results when used with the PostgreSQL DATE_ADD and DATE_SUBTRACT functions. The CENTURY, DECADE, DOW, DOY, EPOCH, and MILLENNIUM intervals cause an exception to be thrown.

                                      • Workaround: Convert the interval into a DAY, MONTH, or YEAR interval.
                                    • CLOUDS-3409: A NullPointerException may be thrown when an UPDATE statement contains a sub-query.

                                      • Workaround: Remove the sub-query from the UPDATE statement and execute it separately. Then use the result of the sub-query in the UPDATE statement.
                                    • CLOUDS-3601: The third-party libraries packaged with the Protegrity JDBC driver may be different from the versions of the same libraries used by your application. This can cause exceptions or undefined behavior when the versions do not match.

                                      • Workarounds:
                                        • See this section on how to install Protegrity JDBC Driver using Apache Maven.
                                        • Load the Protegrity JDBC driver in an isolated ClassLoader.
                                    • CLOUDS-3602: The Protegrity Application Protector - JDBC includes the SLF4J library for your convenience in case your application does not already have SLF4J. Additional or different JAR files may be required to properly integrate the Protegrity JDBC driver logs with your application logging.

                                      • Workarounds:
                                        • See this section on how to install Protegrity JDBC Driver using Apache Maven.
                                        • Load the Protegrity JDBC driver in an isolated ClassLoader and use the included SLF4J Simple logging.
                                    • CLOUDS-3722: Some data type conversions are not supported and throw an exception when they include a protected timestamp column with more than 3 digits of sub-second precision, such as TIMESTAMP(6) or TIMESTAMP(9). This includes converting from / to CHAR, VARCHAR, DATE, TIME, TIMESTAMP(0), and TIMESTAMP(3) columns.

                                      • Workaround: Perform the data type conversion in Java then use the result in your SQL query.
                                    • CLOUDS-3783: Sorting on a protected column uses lexicographic ordering based on the Unicode value of each character. This ordering may be different from cleartext columns that use the database’s collation-based ordering which includes locale-specific ordering.

                                      • Workaround: Re-order the rows in Java if locale-specific ordering is required.
                                    • CLOUDS-6456: XA transaction support is only available for PostgreSQL.

                                    • CLOUDS-6539: When using SQL Server JDBC Driver version 13.x, Protector does not resolve references to the dbo schema. References to dbo result in the error “Object ‘dbo’ not found within ‘adhoc.’”.

                                      • Workaround: Use SQL Server JDBC Driver version 12.x. Alternatively, avoid usage of the dbo schema in SQL queries.
                                    • CLOUDS-6749: A DELETE statement with a sub-query is disabled for all vendors other than PostgreSQL.

                                      • Workaround: Remove the sub-query from the DELETE statement and execute it separately. Then use the result of the sub-query to remove matching rows.
                                    • CLOUDS-7532: The protector will process data from postgres tables with CITEXT, but CITEXT explicitly written into any input statement will throw an error.

                                      • Workaround: Remove explicit CITEXT specifiers in input statements where they are not required.

                                    1.78 -

                                    Stored Procedures

                                    The following limitations apply only to procedure calls:

                                    • Procedure calls must use CallableStatement
                                    • Literal input values to procedure calls are not protected
                                    • Procedure calls that produce a ResultSet are not unprotected

                                    1.79 -

                                    SQL Statements

                                    The JDBC Protector can execute DQL and DML statements, such as SELECT, INSERT, UPDATE, and DELETE, in a variety of vendor-specific dialects. While a wide range of vendor-specific SQL extensions are supported, there is no guarantee that the JDBC Protector will handle every SQL statement without modification. The following SQL statements are known to not be supported:

                                    • DDL statements such as CREATE, ALTER, or DROP
                                    • DCL statements such as GRANT or REVOKE
                                    • DELETE statements with a sub-query are supported only on PostgreSQL
                                    • UPSERT statements
                                    • Some vendor-specific SQL extensions are not supported, including:
                                      • Informix: Sequences are not supported
                                      • MariaDB: Sequences are not supported
                                      • PostgreSQL: ON CONFLICT statements which contain DO UPDATE or ON CONSTRAINT, or which do not use dynamic parameters in a PreparedStatement for protected columns

                                    The application can bypass the JDBC Protector and invoke these methods from the underlying native driver’s connection; however, this will not utilize the JDBC Protector’s transparent protection capabilities.

                                    1.80 -

                                    Troubleshooting

                                    Error MessageAction
                                    java.sql.SQLException: No suitable driver found for jdbc:iap:...
                                    1. Verify that the protegrity-jdbc-<version>.jar file has been added to the Java classpath for your application.
                                    2. If your application allows setting the JDBC driver class name, ensure that it has been set to com.protegrity.jdbc.Driver.
                                    3. Try registering the driver by adding the following Java code to your application:
                                      Class.forName("com.protegrity.jdbc.Driver");
                                    Missing "uri" in protect configuration properties
                                    1. Verify that the cloud-protect.properties file has been added to the classpath.
                                    2. Ensure that it contains an uri= entry.
                                    Invalid "uri" in protect configuration propertiesVerify that the protegrity-protect-<platform>-<version>.jar file has been added to the classpath.
                                    AP Java library not found
                                    1. Verify that AP Java has been installed.
                                    2. Ensure that the uri in the cloud-protect.properties file contains rps://esa.example.com:443 followed by the path to your AP Java installation.
                                    Init library failedVerify that the PEP Server is running and is able to connect to ESA.
                                    Policy not available
                                    1. Verify that the PEP Server is able to access your ESA server.
                                    2. Ensure that a policy has been deployed to your PEP Server.
                                    S3 policy file missing IMMUTABLE_POLICY_PACKAGE entryVerify that the uri in the cloud-protect.properties file is the URL of a valid Protegrity policy file.
                                    SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder". SLF4J: Defaulting to no-operation (NOP) logger implementationAdd an SLF4J binding to your classpath. The Simple binding can be downloaded from Maven.
                                    Failed to encode .. in charaset set ...Set the JVM property calcite.default.charset to the character set you want to use.
                                    Informix: A syntax error has occurred.Verify that DELIMIDENT=Y has been added to your JDBC URL.
                                    SQL SELECT statement with large IN subquery fails with java.lang.StackOverflowErrorAdd InSubqueryThreshold SQL hint to your SELECT statement. This hint tells JDBC Protector to use an alternative SQL query. Sample SQL statement: SELECT /*+ InSubqueryThreshold */ full_name FROM employee WHERE ...

                                    2 -