SQL Reference: Data Definition Statements

SQL Reference: Data Definition Statements
Teradata Database
SQL Reference
Data Definition Statements
Release 12.0
B035-1144-067A
March 2010
The product or products described in this book are licensed products of Teradata Corporation or its affiliates.
Teradata, BYNET, DBC/1012, DecisionCast, DecisionFlow, DecisionPoint, Eye logo design, InfoWise, Meta Warehouse, MyCommerce,
SeeChain, SeeCommerce, SeeRisk, Teradata Decision Experts, Teradata Source Experts, WebAnalyst, and You’ve Never Seen Your Business Like
This Before are trademarks or registered trademarks of Teradata Corporation or its affiliates.
Adaptec and SCSISelect are trademarks or registered trademarks of Adaptec, Inc.
AMD Opteron and Opteron are trademarks of Advanced Micro Devices, Inc.
BakBone and NetVault are trademarks or registered trademarks of BakBone Software, Inc.
EMC, PowerPath, SRDF, and Symmetrix are registered trademarks of EMC Corporation.
GoldenGate is a trademark of GoldenGate Software, Inc.
Hewlett-Packard and HP are registered trademarks of Hewlett-Packard Company.
Intel, Pentium, and XEON are registered trademarks of Intel Corporation.
IBM, CICS, DB2, MVS, RACF, Tivoli, and VM are registered trademarks of International Business Machines Corporation.
Linux is a registered trademark of Linus Torvalds.
LSI and Engenio are registered trademarks of LSI Corporation.
Microsoft, Active Directory, Windows, Windows NT, and Windows Server are registered trademarks of Microsoft Corporation in the United
States and other countries.
Novell and SUSE are registered trademarks of Novell, Inc., in the United States and other countries.
QLogic and SANbox trademarks or registered trademarks of QLogic Corporation.
SAS and SAS/C are trademarks or registered trademarks of SAS Institute Inc.
SPARC is a registered trademarks of SPARC International, Inc.
Sun Microsystems, Solaris, Sun, and Sun Java are trademarks or registered trademarks of Sun Microsystems, Inc., in the United States and other
countries.
Symantec, NetBackup, and VERITAS are trademarks or registered trademarks of Symantec Corporation or its affiliates in the United States
and other countries.
Unicode is a collective membership mark and a service mark of Unicode, Inc.
UNIX is a registered trademark of The Open Group in the United States and other countries.
Other product and company names mentioned herein may be the trademarks of their respective owners.
THE INFORMATION CONTAINED IN THIS DOCUMENT IS PROVIDED ON AN “AS-IS” BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION
MAY NOT APPLY TO YOU. IN NO EVENT WILL TERADATA CORPORATION BE LIABLE FOR ANY INDIRECT, DIRECT, SPECIAL, INCIDENTAL,
OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS OR LOST SAVINGS, EVEN IF EXPRESSLY ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
The information contained in this document may contain references or cross-references to features, functions, products, or services that are
not announced or available in your country. Such references do not imply that Teradata Corporation intends to announce such features,
functions, products, or services in your country. Please consult your local Teradata Corporation representative for those features, functions,
products, or services available in your country.
Information contained in this document may contain technical inaccuracies or typographical errors. Information may be changed or updated
without notice. Teradata Corporation may also make improvements or changes in the products or services described in this information at any
time without notice.
To maintain the quality of our products and services, we would like your comments on the accuracy, clarity, organization, and value of this
document. Please e-mail: teradata-books@lists.teradata.com
Any comments or materials (collectively referred to as “Feedback”) sent to Teradata Corporation will be deemed non-confidential. Teradata
Corporation will have no obligation of any kind with respect to Feedback and will be free to use, reproduce, disclose, exhibit, display, transform,
create derivative works of, and distribute the Feedback and derivative works thereof without limitation on a royalty-free basis. Further, Teradata
Corporation will be free to use any ideas, concepts, know-how, or techniques contained in such Feedback for any purpose whatsoever, including
developing, manufacturing, or marketing products or services incorporating Feedback.
Copyright © 2000 - 2010 by Teradata Corporation. All Rights Reserved.
Preface
Purpose
SQL Reference: Data Definition Statements describes Teradata Database SQL language
statements used to perform the following actions:
•
Define or restructure the database (Data Definition Language)
•
Assign or revoke access to the data (Data Control Language)
•
Analyze queries and query workloads
•
Use data definition tools to assist SQL programming
This preface describes the organization of SQL Reference: Data Definition Statements and
identifies information you should know before using it. This book should be used in
conjunction with the other volumes of Teradata Database SQL Reference.
Audience
System administrators, database administrators, and security administrators are the principal
audience for this manual. Teradata field engineers and other technical personnel responsible
for designing and maintaining the Teradata Database may also find this manual useful.
Supported Software Release
This book supports Teradata® Database 12.0.
Prerequisites
If you are not familiar with the Teradata Database, you will find it useful to read the
Introduction to Teradata Warehouse and SQL Reference: Fundamentals before reading this
document.
Additional information about developing applications using embedded SQL is found in
Teradata Preprocessor2 for Embedded SQL Programmer Guide.
You should be familiar with basic relational database management theory and technology.
This manual is not an SQL primer.
SQL Reference: Data Definition Statements
3
Preface
Changes To This Book
Changes To This Book
This book includes the following changes:
Date
Teradata
Database 12.0
March 2010
Teradata
Database 12.0
Description
Updated the following statements:
•
•
•
•
•
ALTER TABLE
COLLECT STATISTICS (Optimizer Form)
CREATE TABLE
DIAGNOSTIC COSTPRINT
ONLINE ARCHIVE LOGGING ON
• Clarified collecting statistics on global temporary tables.
• Revised definition of non-updatable (read-only) views.
November 2009
Teradata
Database 12.0
August 2009
Teradata
Database 12.0
October 2007
4
• Corrected “Rules for Creating, Replacing, and Using Views”: the system does
not return an error when you perform a HELP VIEW or SHOW VIEW
request against a semantically invalid view.
• Provided correct system maximum for replication groups.
• Clarified rules for using parameters inside a macro.
• Corrected CREATE FUNCTION for DETERMINISTIC
• Updated CREATE PROCEDURE (SQL Form) to note QUERY_BAND cannot
be an assignment-target variable
• Updated CREATE TRIGGER for query bands
• Corrected HELP STATISTICS
SQL Reference: Data Definition Statements
Preface
Changes To This Book
Date
Teradata
Database 12.0
September 2007
SQL Reference: Data Definition Statements
Description
• Added list of automatically granted privileges to all ALTER, CREATE, and
MODIFY statements.
• Added the following new statements:
• CREATE ERROR TABLE
• DIAGNOSTIC COSTPRINT
• DIAGNOSTIC DUMP COSTS
• DIAGNOSTIC HELP COSTS
• DIAGNOSTIC SET COSTS
• DROP ERROR TABLE
• HELP ERROR TABLE
• INITIATE PARTITION ANALYSIS
• LOGGING ONLINE ARCHIVE OFF
• LOGGING ONLINE ARCHIVE ON
• SET QUERY_BAND
• SHOW ERROR TABLE
• Added Java support to ALTER PROCEDURE (External Form).
• Added the following to ALTER TABLE:
• Support for multilevel partitioned primary indexes.
• Support for error tables.
• Added COMPILE option to ALTER TYPE.
• Added VARYING COLUMNS option to CREATE FUNCTION (Table Form).
• Added the following to CREATE HASH INDEX:
• Restrictions regarding use of PARTITION#Ln columns in the definition of
a hash index.
• Restriction on creating hash indexes on error tables.
• Added the following to CREATE INDEX:
• Restrictions regarding use of PARTITION#Ln columns in the definition of
a secondary index.
• Support for error tables.
5
Preface
Changes To This Book
Date
Teradata
Database 12.0
September 2007
(continued)
6
Description
• Added the following to CREATE JOIN INDEX:
• Restrictions regarding use of PARTITION#Ln columns in the definition of
a join index.
• Restrictions on collecting statistics on PARTITION#Ln columns.
• Restriction on creating a join index for an error table.
• Multilevel partitioned primary index support for noncompressed join
indexes.
• Usage information regarding partitioned primary indexes for join indexes.
• Added support for query bands to CREATE MACRO.
• Added the following to CREATE PROCEDURE (External Form):
• Support for Java external stored procedures.
• Support for SQL in external stored procedures using CLIv2 calls.
• Support for dynamic result sets.
• Extensions to SQL data access options.
• Added the following to CREATE PROCEDURE (SQL Form):
• Support for dynamic SQL using PREPARE and EXECUTE statements.
• Support for cursor scrollability.
• Support for dynamic result sets.
• Extensions to SQL data access options.
• Added the following to CREATE TABLE:
• Support for multilevel partitioned primary indexes.
• Support for error tables.
• Clarification of the difference between value compression and hash and
join index compression.
• Clarification on noncost of uncompressing compressed column values.
• Tips on how best to optimize queries to ensure that partition elimination
occurs.
• Added support for error tables to CREATE TABLE (Queue Table Form).
• Added the following to CREATE TRIGGER:
• Restrictions on defining triggers on error tables.
• Comparison of the execution sequence of triggers for Teradata MERGE
statements and the trigger execution sequence for MERGE statements
defined by the ANSI SQL standard.
• Added information about controlling access to PPI table partitions to
CREATE VIEW.
• Added restrictions on the following to DELETE DATABASE:
• Error tables.
• Java external stored procedures.
• Online archive logging.
• Added restrictions on Java external stored procedures to DROP DATABASE.
• Added restrictions on Java external stored procedures to DROP
PROCEDURE.
SQL Reference: Data Definition Statements
Preface
Changes To This Book
Date
Teradata
Database 12.0
September 2007
(continued)
SQL Reference: Data Definition Statements
Description
• Added restrictions on the following to DROP TABLE:
• Error tables.
• Online archive logging.
• Added the COST PROFILE option to MODIFY PROFILE.
• Added a complete list of privilege abbreviations to GRANT (SQL Form).
• Added the following to COLLECT STATISTICS (Optimizer Form)
• Restrictions on collecting statistics on the system-derived PARTITION#Ln
columns.
• New topic on collecting statistics on the system-derived PARTITION and
PARTITION#Ln columns.
• Update to description of how locks are placed when statistics are collected.
• Added information about how DUMP EXPLAIN is affected by request cache
peeking.
• Added TIME LIMIT option to INITIATE INDEX ANALYSIS.
• Added information about how INSERT EXPLAIN is affected by request cache
peeking.
• Added support for error tables to HELP COLUMN
• Updated HELP FUNCTION for dynamic row result sets.
• Updated HELP PROCEDURE for Java external stored procedures.
• Updated HELP SESSION for query bands.
• Updated HELP STATISTICS (Optimizer Form) for the following:
• Restrictions on reporting statistics for system-derived PARTITION#Ln
columns.
• Support for the NumAllNulls and AvgAmpRPV statistics.
• Updated HELP STATISTICS (QCD Form) for restrictions on reporting
statistics for system-derived PARTITION#Ln columns.
• Performed DR fixes and enhancement requests.
7
Preface
Changes To This Book
Date
Teradata
V2R6.2
September 2006
Description
• Updated multiple statements for new BIGINT and large DECIMAL data
types.
• Updated ALTER TABLE for multivalued compression.
• Updated CREATE HASH INDEX, CREATE INDEX, and CREATE JOIN
INDEX to note that you cannot specify the system-derived PARTITION
column in any index definition.
• Updated CREATE JOIN INDEX to remove the restriction on defining join
indexes and triggers on the same table.
• Updated CREATE JOIN INDEX for PPI support for uncompressed join
indexes.
Also noted that you cannot collect statistics on the system-generated
PARTITION column for PPI join indexes.
• Updated CREATE JOIN INDEX with criteria for deciding whether to
implement a PPI join index or an NPPI join index with a value-ordered NUSI
to support range queries.
• Updated CREATE TABLE to remove restrictions on creating global temporary
and volatile tables with a partitioned primary index.
• Updated CREATE TABLE … AS for copied statistics.
• Updated CREATE TABLE to note that you cannot collect statistics on the
system-generated PARTITION column for PPI global temporary and volatile
tables.
• Updated CREATE TRIGGER to remove the restriction on defining join
indexes and triggers on the same table.
• Updated CREATE TRIGGER for batch referential integrity support.
• Added information on what not to include in a workload to INITIATE
INDEX ANALYSIS.
• Updated HELP SESSION for the BIGINT data type and for the default read
lock isolation level.
8
SQL Reference: Data Definition Statements
Preface
Additional Information
Additional Information
Additional information that supports this product and the Teradata Database is available at
the following Web sites:
Type of Information
Description
Overview of the
release
The Release Definition provides the
following information:
Information too
late for the
manuals
• Overview of all the products in the
release
• Information received too late to be
included in the manuals
• Operating systems and Teradata
Database versions that are certified to
work with each product
• Version numbers of each product and
the documentation for each product
• Information about available training
and support center
Additional
information
related to this
product
Use the Teradata Information Products
Publishing Library site to view or
download the most recent versions of all
manuals.
Specific manuals that supply related or
additional information to this manual
are listed.
CD-ROM images
Ordering
information for
manuals
SQL Reference: Data Definition Statements
This site contains a link to a
downloadable CD-ROM image of all
customer documentation for this release.
Customers are authorized to create CDROMs for their use from this image.
Use the Teradata Information Products
Publishing Library site to order printed
versions of manuals.
Source
http://www.info.teradata.com/
Click General Search. In the
Publication Product ID field,
enter 1725 and click Search to
bring up the following Release
Definition:
• Base System Release Definition
B035-1725-067K
http://www.info.teradata.com/
Click General Search, and do one
of the following:
• In the Product Line field,
select Software - Teradata
Database for a list of all of the
publications for this release,
• In the Publication Product ID
field, enter a book number.
http://www.info.teradata.com/
Click General Search. In the Title
or Keyword field, enter CD-ROM,
and click Search.
http://www.info.teradata.com/
Click How to Order under Print &
CD Publications.
9
Preface
References to Microsoft Windows and Linux
Type of Information
General
information about
Teradata
Description
Source
Teradata.com
The Teradata home page provides links
to numerous sources of information
about Teradata. Links include:
• Executive reports, case studies of
customer experiences with Teradata,
and thought leadership
• Technical information, solutions, and
expert advice
• Press releases, mentions and media
resources
References to Microsoft Windows and Linux
This book refers to “Microsoft Windows” and “Linux.” For Teradata Database 12.0, these
references mean the following:
•
“Windows” is Microsoft Windows Server 2003 32-bit and Microsoft Windows Server 2003
64-bit.
•
“Linux” is SUSE Linux Enterprise Server 9 and SUSE Linux Enterprise Server 10.
Teradata plans to release Teradata Database support for SUSE Linux Enterprise Server 10
before the next major or minor release of the database. Therefore, information about this
SUSE release is included in this document. The announcement regarding availability of SUSE
Linux Enterprise Server 10 will be made after Teradata Database 12.0 GCA. Please check with
your account representative regarding SUSE Linux Enterprise Server 10 availability in your
location.
10
SQL Reference: Data Definition Statements
Table of Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Audience . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Supported Software Release . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
Changes To This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .4
Additional Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .9
References to Microsoft Windows and Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Chapter 1: SQL DDL Syntax
(ALTER FUNCTION - COMMENT) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
ALTER FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
ALTER METHOD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
ALTER PROCEDURE (External Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
ALTER PROCEDURE (SQL Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
ALTER REPLICATION GROUP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
ALTER TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
ALTER TRIGGER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
ALTER TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
BEGIN LOGGING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
COMMENT (Comment Placing Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165
SQL Reference: Data Definition Statements
11
Table of Contents
Chapter 2: SQL DDL Syntax
(CREATE AUTHORIZATION - CREATE ROLE) . . . . . . . . . . . . . . . . . . . .173
CREATE AUTHORIZATION/REPLACE AUTHORIZATION. . . . . . . . . . . . . . . . . . . . . . . .174
CREATE CAST/REPLACE CAST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .184
CREATE DATABASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
CREATE ERROR TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .205
CREATE FUNCTION/REPLACE FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .222
CREATE FUNCTION (Table Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .279
CREATE GLOBAL TEMPORARY TRACE TABLE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .303
CREATE HASH INDEX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .316
CREATE INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .336
CREATE JOIN INDEX. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .346
CREATE MACRO/ REPLACE MACRO. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .416
CREATE METHOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .431
CREATE ORDERING/REPLACE ORDERING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .455
CREATE PROCEDURE (External Form)/REPLACE PROCEDURE (External Form) . . . . .463
CREATE PROCEDURE (SQL Form)/REPLACE PROCEDURE. . . . . . . . . . . . . . . . . . . . . . .529
CREATE PROFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .578
CREATE RECURSIVE VIEW/REPLACE RECURSIVE VIEW . . . . . . . . . . . . . . . . . . . . . . . .587
CREATE REPLICATION GROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .626
CREATE ROLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .641
Chapter 3: SQL DDL Syntax
(CREATE TABLE - CREATE VIEW) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .647
CREATE TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .648
CREATE TABLE (Table Kind Clause) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .673
CREATE TABLE (Table Options Clause). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .680
CREATE TABLE (Column Definition Clause) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .685
CREATE TABLE (Index Definition Clause). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .716
CREATE TABLE (Temporary/Volatile Table Preservation Clause) . . . . . . . . . . . . . . . . . . . .749
CREATE TABLE (AS Clause) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .750
CREATE TABLE (Examples) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .766
CREATE TABLE (Queue Table Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .817
CREATE TRANSFORM/REPLACE TRANSFORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .855
CREATE TRIGGER/REPLACE TRIGGER. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .870
12
SQL Reference: Data Definition Statements
Table of Contents
CREATE TYPE (Distinct Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 906
CREATE TYPE (Structured Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
CREATE USER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 950
CREATE VIEW/REPLACE VIEW. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 971
Chapter 4: SQL DDL Syntax
(DATABASE - SET TIME ZONE) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 993
DATABASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 995
DELETE DATABASE/DELETE USER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997
DROP AUTHORIZATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1001
DROP CAST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1003
DROP DATABASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1007
DROP ERROR TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1011
DROP FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1013
DROP HASH INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1018
DROP INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1020
DROP JOIN INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1025
DROP MACRO/DROP PROCEDURE/DROP TABLE/DROP TRIGGER/DROP VIEW 1027
DROP ORDERING. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1032
DROP PROFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1034
DROP REPLICATION GROUP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1036
DROP ROLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1038
DROP TRANSFORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1041
DROP TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1043
DROP USER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1045
END LOGGING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1049
LOGGING ONLINE ARCHIVE OFF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1054
LOGGING ONLINE ARCHIVE ON. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1058
MODIFY DATABASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1071
MODIFY PROFILE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1078
MODIFY USER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1086
RENAME FUNCTION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1104
RENAME MACRO/RENAME PROCEDURE/ RENAME TABLE/RENAME TRIGGER/
RENAME VIEW. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1109
REPLACE METHOD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1112
SET QUERY_BAND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1121
SET ROLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1136
SQL Reference: Data Definition Statements
13
Table of Contents
SET SESSION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1139
SET SESSION ACCOUNT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1144
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL. . . . . . . . 1148
SET SESSION COLLATION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1153
SET SESSION DATABASE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1159
SET SESSION DATEFORM. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1160
SET SESSION FUNCTION TRACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1162
SET SESSION OVERRIDE REPLICATION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1165
SET TIME ZONE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1167
Chapter 5: SQL DCL Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1169
Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1171
Owners, Creators, and Users . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1173
Types of Privileges. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1176
Implicit Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1180
Explicit Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1181
Summary of Implicit and Explicit Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1183
Automatically Granted Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1184
Inherited Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1185
PUBLIC Privileges. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1186
Summary of Implicit, Automatic, Explicit, and Inherited Privilege Types . . . . . . . . . . . . . 1187
GIVE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1188
GRANT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1191
GRANT (Monitor Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1192
GRANT (Role Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1196
GRANT (SQL Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1199
GRANT LOGON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1236
REVOKE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1241
REVOKE (Monitor Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1243
REVOKE (Role Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1247
REVOKE (SQL Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1250
REVOKE LOGON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1266
14
SQL Reference: Data Definition Statements
Table of Contents
Chapter 6: Query and Workload Analysis Statements . . . . . . 1269
SQL Statements Described In This Chapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1271
Query and Workload Analysis Statements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1272
BEGIN QUERY LOGGING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1273
COLLECT DEMOGRAPHICS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1289
COLLECT STATISTICS (Optimizer Form). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1292
COLLECT STATISTICS (QCD Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1322
DROP STATISTICS (Optimizer Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1329
DROP STATISTICS (QCD Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1336
DUMP EXPLAIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1339
END QUERY LOGGING . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1344
INITIATE INDEX ANALYSIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1346
INITIATE PARTITION ANALYSIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1359
INSERT EXPLAIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1363
RESTART INDEX ANALYSIS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1374
Diagnostic Tools for Target Level Emulation and the Teradata Index Wizard. . . . . . . . . . 1377
DIAGNOSTIC COSTPRINT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1378
DIAGNOSTIC DUMP COSTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1379
DIAGNOSTIC HELP COSTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1381
DIAGNOSTIC SET COSTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1383
DIAGNOSTIC HELP PROFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1389
DIAGNOSTIC SET PROFILE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1394
DIAGNOSTIC DUMP SAMPLES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1400
DIAGNOSTIC HELP SAMPLES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1402
DIAGNOSTIC SET SAMPLES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1404
DIAGNOSTIC "Validate Index" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1408
SQL Reference: Data Definition Statements
15
Table of Contents
Chapter 7: SQL HELP and SHOW Statements . . . . . . . . . . . . . . . . . 1415
HELP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1418
HELP CAST. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1427
HELP COLUMN. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1431
HELP CONSTRAINT. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1450
HELP DATABASE/HELP USER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1456
HELP ERROR TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1461
HELP FUNCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1464
HELP HASH INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1472
HELP INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1474
HELP JOIN INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1482
HELP MACRO/HELP TABLE/HELP VIEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1484
HELP METHOD. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1493
HELP PROCEDURE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1499
HELP REPLICATION GROUP. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1507
HELP SESSION. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1510
HELP STATISTICS (Optimizer Form). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1523
HELP STATISTICS (QCD Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1543
HELP TRANSFORM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1555
HELP TRIGGER . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1558
HELP TYPE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1561
HELP VOLATILE TABLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1575
HELP (Online Form) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1578
SHOW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1581
SHOW CAST/SHOW ERROR TABLE/SHOW FUNCTION/SHOW HASH INDEX/
SHOW JOIN INDEX/SHOW MACRO/SHOW METHOD/SHOW PROCEDURE/
SHOW REPLICATION GROUP/SHOW TABLE/SHOW TRIGGER/SHOW TYPE/
SHOW VIEW . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1588
16
SQL Reference: Data Definition Statements
Table of Contents
Appendix A: Notation Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1605
Syntax Diagram Conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1606
Character Shorthand Notation Used In This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1610
Predicate Calculus Notation Used in This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1612
Appendix B: ANSI SQL Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1613
The Individual ANSI SQL Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1614
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1617
Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1631
SQL Reference: Data Definition Statements
17
Table of Contents
18
SQL Reference: Data Definition Statements
SQL DDL Syntax
(ALTER FUNCTION - COMMENT)
CHAPTER 1
Chapters 1 through 4 document Teradata Database SQL data definition language (DDL)
statements in alphabetical order. DDL statements define, revise, and remove database objects.
This chapter documents the following statements:
•
“ALTER FUNCTION” on page 21
•
“ALTER METHOD” on page 28
•
“ALTER PROCEDURE (External Form)” on page 34
•
“ALTER PROCEDURE (SQL Form)” on page 40
•
“ALTER REPLICATION GROUP” on page 49
•
“ALTER TABLE” on page 53
•
“ALTER TRIGGER” on page 140
•
“ALTER TYPE” on page 142
•
“BEGIN LOGGING” on page 155
•
“COMMENT (Comment Placing Form)” on page 166
Chapter 2: “SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)” documents
CREATE AUTHORIZATION through CREATE ROLE.
Chapter 3: “SQL DDL Syntax (CREATE TABLE - CREATE VIEW)” documents CREATE
TABLE through CREATE VIEW.
Chapter 4: “SQL DDL Syntax (DATABASE - SET TIME ZONE)” documents DATABASE
through SET TIME ZONE.
Chapter 5: “SQL DCL Syntax” documents the Teradata Database SQL data control language
(DCL) statements.
Chapter 6: “Query and Workload Analysis Statements” documents SQL query and workload
analysis statements.
Chapter 7: “SQL HELP and SHOW Statements” documents Teradata Database SQL HELP
and SHOW statements.
SQL Reference: Data Definition Statements
19
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
Experienced SQL users can also see the simplified DDL statement descriptions in SQL/Data
Dictionary Quick Reference.
Teradata Database SQL data manipulation language (DML) statements, with the exception of
those specific to stored procedures and embedded SQL, are described in SQL Reference: Data
Manipulation Statements.
The functions and operators used in Teradata Database SQL data manipulation language
(DML) statements are described in SQL Reference: Functions and Operators.
Teradata Database SQL statements exclusive to stored procedures and embedded SQL
applications are described in SQL Reference: Stored Procedures and Embedded SQL.
Documentation related to writing external user-defined functions and stored procedures is
found in SQL Reference: UDF, UDM, and External Stored Procedure Programming.
20
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
ALTER FUNCTION
Purpose
Performs either or both of the following functions:
•
Controls whether an existing function can run in protected mode as a separate process or
in non-protected mode as part of the database.
•
Recompiles or relinks the function and redistributes it.
Use the REPLACE FUNCTION statement to alter other characteristics of an existing function
(see “CREATE FUNCTION/ REPLACE FUNCTION” on page 222).
Syntax
ALTER
A
specific_function_name
SPECIFIC FUNCTION
database_name.
function_name
FUNCTION
,
database_name.
(
A
EXECUTE
data_type
UDT_name
)
PROTECTED
NOT
;
COMPILE
ONLY
1101C097
where:
Syntax element …
Specifies …
SPECIFIC FUNCTION
that the following character string is the specific function name for the
function to be altered.
database_name
the containing database for specific_function_name, if something other
than the current database.
specific_function_name
the specific function name for the function to be altered.
FUNCTION
that the following character string is the function name for the function
to be altered.
database_name
the containing database for function_name, if something other than the
current database.
function_name
the function name for the function to be altered.
SQL Reference: Data Definition Statements
21
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
Syntax element …
Specifies …
data_type
an optional data type specification for the parameters passed to
function_name.
If you do not specify a data type list, then the specified function must be
the only one with that name in the database.
[SYSUDTLIB.]
UDT_name
the name of any UDT included in the list of data types for function_name.
EXECUTE PROTECTED
to change the execution mode for the specified function from
unprotected mode to protected mode (see “When to Specify Unprotected
Mode” on page 22 for details).
EXECUTE NOT
PROTECTED
to change the execution mode for the specified function from protected
mode to unprotected mode (see “When to Specify Unprotected Mode”
on page 22 for details).
COMPILE [ONLY]
to recompile the code source for the specified function, generate the
object code, recreate the .so or .dll, and distribute it to all nodes of
the system.
The existing function object is replaced by the recompiled version.
ANSI Compliance
ALTER FUNCTION is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
To alter a function definition, you must have the ALTER FUNCTION privilege on that
function.
Privileges Granted Automatically
None.
When to Specify Unprotected Mode
To protect the system from new external routines that have not passed your quality metrics,
the default execution mode for all external routines is EXECUTE PROTECTED. If the default
specification for CREATE/REPLACE FUNCTION were EXECUTE NOT PROTECTED, then
an error in the created function could crash the system.
22
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
Protected mode is a database state that traps on memory address violations, corrupted data
structures, and illegal computations, such as divide-by-zero, to ensure they do not crash the
system.1 This execution mode isolates all of the data the external routine might access as a
separate process, or “server” in its own local work space (see SQL Reference: UDF, UDM, and
External Stored Procedure Programming for details). If any memory violation or other system
error occurs, then the error is localized to the routine and the transaction executing it, not the
entire database (see “Protected and Unprotected Modes” on page 292 for more information).
Because this isolation also makes the routine run slower, you should change its protection
mode to unprotected once it has passed all your quality metrics for being put into production
use. You change the execution mode for the routine with a simple ALTER FUNCTION
statement (see “ALTER FUNCTION” on page 21) and specifying the EXECUTE NOT
PROTECTED option.
Do not make this change for any UDF that makes OS system calls. Any such UDF should
always be run in protected mode. You do not need to recompile or relink the external routine
after changing its protection mode.
As a rule, the DBA2 should only specify direct execution mode (assigned by the EXECUTE
NOT PROTECTED option) for a function that performs CPU-only operations after it has
been thoroughly debugged. Never run external routines that cause the OS to consume system
resources in unprotected mode.3
The following table summarizes how the UDF protection mode options should be used:
IF …
THEN specify …
you are still developing and debugging a
function
EXECUTE PROTECTED.
the function opens a file or uses another
operating system resource that requires
tracking by the operating systema
EXECUTE PROTECTED.
the function is a computational function
that does not use any operating system
resources
EXECUTE NOT PROTECTED.
Running such a function in unprotected mode could
interfere with the proper operation of the Teradata
Database.
Running a UDF in unprotected mode speeds up the
processing of the function considerably.
Use this option only after thoroughly debugging the
function and making sure it produces the correct
output.
a. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
1. Protected mode does not detect or protect against CPU and memory loops or operating system I/Os such
as opening external files to read from or write to them.
2. No other user than the DBA, not even the software engineer that writes a UDF, should be granted the
privileges to alter it to run in unprotected mode.
3. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
SQL Reference: Data Definition Statements
23
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
UDF Servers
Protected mode UDFs, including secure mode UDFs, run under a separate process called a
server. UDFs set up to require external security run in a subtype of protected mode called
secure mode. The system sets up separate processes, or servers, to support both protected
mode and secure mode functions (see SQL Reference: UDF, UDM, and External Stored
Procedure Programming for details).
The following series of events occurs the first time a secure mode4 UDF is invoked in a session:
1
The UDF server set-up logic looks at the authorization and determines whether a secure
server process is already set up for the given OS user authorization.
Because this is the first time the UDF has been invoked in the session, no secure server
process has been set up.
2
The authorization is not set up, so the process validates the OS user by making a validation
check on the user name and password.
For Windows systems, a logon token is obtained.
If the logon attempt using the provided authorization information fails, the system returns
an error to the session.
3
If the authorization is successful, the system creates the secure server process and the UDF
executes.
If this is not the first time the UDF has been executed for the session, the following series of
events occurs:
1
The UDF secure server set-up logic reads the authorization and determines that there is
already a secure server process set up with that authorization.
2
The UDF is executed using the existing secure server.
If the maximum number of secure servers has been created and a new request comes in for a
given authorization for which there is no established secure server, the following series of
events occurs:
1
The UDF secure server logic attempts to find a secure server with the given authorization.
It does not find one and determines that the maximum number of secures servers has
already been set up.
2
The authorization is not set up, so the process validates the OS user by making a validation
check on the user name and password.
For Windows systems, a logon token is obtained.
If the logon attempt using the provided authorization information fails, the system returns
an error to the session.
3
The UDF secure server logic finds the least used secure server process and terminates it.
4
The new secure server process is created and the UDF is executed.
4. The process is essentially identical for protected mode UDFs.
24
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
Recompiling and Redistributing an Existing Function
The COMPILE option is intended to be used by DBAs to recompile functions that have been
moved to a platform, system, or restored database other than the one in which they were
created.
Specify the COMPILE option to recompile an existing function. If its source code is present,
then the system recompiles it, generates the object, recreates the .dll or .so file, and
distributes it to all nodes of the system. The object is replaced with the recompiled version.
If the function was created with the object only (that is, there is no source code present to be
recompiled), the function object is used to recreate the .dll or .so file and distribute it to
all nodes of the system.
If the function is restored from a different platform to a new platform whose objects are not
compatible, the COMPILE option fails. When this happens, you must recreate the function
with the correct object or source code.
You cannot specify this option if the function was installed as part of a package.
Functions defined to run in unprotected mode and recompiled with this option do not retain
the ability to run in unprotected mode unless you specify EXECUTE NOT PROTECTED (see
“When to Specify Unprotected Mode” on page 22) as part of a follow-up ALTER FUNCTION
request.
For example, suppose you have a UDF named WriteMQ, which has been set to run in
EXECUTE NOT PROTECTED mode by an ALTER FUNCTION request that was submitted
after the function was created using a CREATE FUNCTION request (see “CREATE
FUNCTION/ REPLACE FUNCTION” on page 222) and then thoroughly debugged. Some
time later, it becomes necessary for WriteMQ to be recompiled for some reason, so you must
perform the following multistep procedure if WriteMQ is to be both recompiled and to retain
its ability to run in unprotected mode:5
1
You first submit the following ALTER FUNCTION request to recompile the WriteMQ
UDF:
ALTER FUNCTION WriteMQ COMPILE;
2
After the successful completion of this request, the system resets the protection mode for
WriteMQ to EXECUTE PROTECTED, so you must run a second ALTER FUNCTION
request to set its protection mode back to EXECUTE NOT PROTECTED:
ALTER FUNCTION WriteMQ EXECUTE NOT PROTECTED;
3
End of procedure.
When you specify COMPILE ONLY, then only the UDF is recompiled and no new dynamic
linked library are distributed to database nodes.
5. Because you cannot specify both COMPILE [ONLY] and EXECUTE [NOT] PROTECTED in the same
ALTER FUNCTION request.
SQL Reference: Data Definition Statements
25
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
When a UDF is loaded onto another platform of a different type, it is marked as non-valid. All
non-valid UDFs must be recompiled. If there are many UDFs in one database, you can save
time by specifying the ONLY option for all but the last compilation in that database to avoid
having to generate and distribute a new library. When you do this, make certain not to specify
the ONLY option for the last UDF you recompile in that database.
One .dll or .so file is built for all UDFs in each database. The .dll or .so files are stored
outside the database on the system disk of each node. If a .dll or .so file becomes
corrupted on one node, the DBA can regenerate it by issuing an ALTER FUNCTION
statement with the COMPILE option to rebuild the .dll or .so file.
To regenerate a corrupted .dll, or .so file, you only need to compile one function in that
database. The system regenerates the .dll, or .so file, and includes all other user-defined
functions defined in that database in the regenerated .dll,or .so file.
Note that changing the protection mode for a UDT-related UDF also causes the
system-generated UDF constructor function to be recompiled invisibly.6
Restrictions on Altering Functions That Implement UDT Transform and
Ordering Functionality
You cannot use ALTER FUNCTION to change the protection mode for a function and to
request its recompilation within the same request. You must submit separate requests to do
this: one to alter the execution protection mode and a second to request the recompilation.
If you attempt to request both a change to the execution mode and a recompilation within the
same request, the system returns an error.
Example 1
Suppose you have created and successfully debugged a UDF named TransXML and you now
want to set its protection mode to EXECUTE NOT PROTECTED. The following request does
that, assuming there is no other UDF in the database named TransXML:
ALTER FUNCTION TransXML EXECUTE NOT PROTECTED;
Example 2
An existing UDF named XPathValue that must be recompiled for some reason. XPathValue
had previously been set to run in unprotected mode. Recall that recompiling a UDF always
resets its protection mode back to protected, so you must follow any recompilation with
another ALTER FUNCTION request to set its protection mode back to unprotected.
The following set of requests recompiles XPathValue and then sets its protection mode back to
unprotected:
ALTER FUNCTION XPathValue COMPILE;
ALTER FUNCTION XPathValue EXECUTE NOT PROTECTED;
6. Invisible in that the system does not return any compilation messages unless the compilation fails for some
reason, in which case the system returns an appropriate error message to the requestor.
26
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER FUNCTION
Related Topics
See the following statements for more information about user-defined functions:
•
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222
•
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303
•
“DROP FUNCTION” on page 1013
•
“RENAME FUNCTION” on page 1104
•
“SET SESSION FUNCTION TRACE” on page 1162
•
“HELP FUNCTION” on page 1464
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
Also see SQL Reference: UDF, UDM, and External Stored Procedure Programming.
SQL Reference: Data Definition Statements
27
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
ALTER METHOD
Purpose
Performs either or both of the following functions:
•
Controls whether an existing method can run in protected mode as a separate process or
in non-protected mode as part of the database.
•
Recompiles or relinks the method and redistributes it.
Use the REPLACE METHOD statement to alter other characteristics of an existing method
(see “REPLACE METHOD” on page 1112).
Syntax
ALTER
specific_method_name
SPECIFIC METHOD
FOR
A
UDT_name
SYSUDTLIB.
method_name
METHOD
INSTANCE
CONSTRUCTOR
SYSUDTLIB.
,
data_type
UDT_name
(
)
SYSUDTLIB.
A
EXECUTE
PROTECTED
;
NOT
COMPILE
ONLY
1101B369
where:
Syntax element …
Specifies …
SPECIFIC METHOD
that the following character string is the specific method name for
the method to be altered.
[SYSUDTLIB.]
specific_method_name
the specific function name for the method to be altered.
INSTANCE METHOD
that the method named as method_name is an instance method.
There must already be a method with the same specific method
name in the database SYSUDTLIB database. If not, the statement
aborts and the system returns an error to the requestor.
This is the default.
CONSTRUCTOR METHOD
28
that the method named as method_name is a constructor method.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
Syntax element …
Specifies …
[SYSUDTLIB.]
method_name
the name (not the specific method name) for the method to be
altered.
There must already be a method associated with the specified
UDT name that has the same signature. If not, the statement
aborts and the system returns an error to the requestor.
data_type
an optional data type specification for the parameters passed to
method_name.
If you do not specify a data type list, then the specified method
must be the only one with that name in the SYSUDTLIB database.
EXECUTE PROTECTED
to change the execution mode for the specified method from
unprotected mode to protected mode (see “When to Specify
Unprotected Mode” on page 29 for details).
EXECUTE NOT PROTECTED
to change the execution mode for the specified method from
protected mode to unprotected mode (see “When to Specify
Unprotected Mode” on page 29 for details).
COMPILE [ONLY]
to recompile the code source for the specified method, generate
the object code, recreate the .so or .dll, and distribute it to all
nodes of the system.
The existing method object is replaced by the recompiled version.
ANSI Compliance
ALTER METHOD is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
To alter a method definition, you must have the UDTMETHOD privilege on the database
SYSUDTLIB.
Privileges Granted Automatically
None.
When to Specify Unprotected Mode
To protect the system from new external routines that have not passed your quality metrics,
the default execution mode for all external routines is EXECUTE PROTECTED. If the default
specification for CREATE METHOD and REPLACE METHOD were EXECUTE NOT
PROTECTED, then an error in the created function could crash the system.
Protected mode is a database state that traps on memory address violations, corrupted data
structures, and illegal computations, such as divide-by-zero, to ensure they do not crash the
system.7 This execution mode isolates all of the data the external routine might access as a
separate process, or “server” in its own local work space (see SQL Reference: UDF, UDM, and
7. Protected mode does not detect or protect against CPU and memory loops or operating system I/Os such
as opening external files to read from or write to them.
SQL Reference: Data Definition Statements
29
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
External Stored Procedure Programming for details). If any memory violation or other system
error occurs, then the error is localized to the routine and the transaction executing it, not the
entire database (see “Protected and Unprotected Modes” on page 292 for more information).
Because this isolation also makes the routine run slower, you should change its protection
mode to unprotected once it has passed all your quality metrics for being put into production
use. You change the execution mode for the routine with a simple ALTER METHOD
statement (see “ALTER METHOD” on page 28) and specifying the EXECUTE NOT
PROTECTED option.
Do not make this change for any method that makes OS system calls. Any such method should
always be run in protected or secure mode. You do not need to recompile or relink the external
routine after changing its protection mode.
As a rule, the DBA8 should only specify direct execution mode (assigned by the EXECUTE
NOT PROTECTED option) for a method that performs CPU-only operations after it has
been thoroughly debugged. Never run external routines that cause the OS to consume system
resources in unprotected mode.9
The following table summarizes how the UDM protection mode options should be used:
IF …
THEN specify …
you are still developing and debugging a
UDM
EXECUTE PROTECTED.
the UDM opens a file or uses another
operating system resource that requires
tracking by the operating systema
EXECUTE PROTECTED.
the UDM does not use any operating
system resources
EXECUTE NOT PROTECTED.
Running such a UDM in unprotected mode could
interfere with the proper operation of the Teradata
Database.
Running a UDM in unprotected mode speeds up
processing considerably.
Use this option only after thoroughly debugging the
UDM and making sure it produces the correct output.
a. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
8. No other user than the DBA, not even the software engineer that writes a UDF, should be granted the
privileges to alter it to run in unprotected mode.
9. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
30
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
Recompiling and Redistributing an Existing Method
The COMPILE option is intended to be used by DBAs to recompile methods that have been
moved to a platform, system, or restored database other than the one in which they were
created.
Specify the COMPILE option to recompile an existing method. If its source code is present,
then the system recompiles it, generates the object, recreates the .dll or .so file, and
distributes it to all nodes of the system. The object is replaced with the recompiled version.
If the method was created with the object only (that is, there is no source code present to be
recompiled), the method object is used to recreate the .dll or .so file and distribute it to all
nodes of the system.
If the method is restored from a different platform to a new platform whose objects are not
compatible, the COMPILE option fails. When this happens, you must recreate the method
with the correct object or source code.
You cannot specify this option if the method was installed as part of a package.
Methods defined to run in unprotected mode and recompiled with this option do not retain
the ability to run in unprotected mode unless you specify EXECUTE NOT PROTECTED (see
“When to Specify Unprotected Mode” on page 29) as part of a follow-up ALTER METHOD
request.
For example, suppose you have a method named in_state() for the UDT named address, and
in_state() has been set to run in EXECUTE NOT PROTECTED mode by an ALTER
METHOD request that was submitted after the method was created using a CREATE
METHOD request (see “CREATE METHOD” on page 431) and then thoroughly debugged.
Some time later, it becomes necessary for in_state() to be recompiled for some reason, so you
must perform the following multistep procedure if in_state() is to be both recompiled and to
retain its ability to run in unprotected mode:10
1
You first submit the following ALTER METHOD request to recompile the in_state()
method:
ALTER METHOD in_state FOR SYSUDTLIB.address COMPILE;
2
After the successful completion of this request, the system resets the protection mode for
in_state() to EXECUTE PROTECTED, so you must run a second ALTER METHOD
request to set its protection mode back to EXECUTE NOT PROTECTED:
ALTER METHOD in_state FOR SYSUDTLIB.address
EXECUTE NOT PROTECTED;
3
End of procedure.
10. Because you cannot specify both COMPILE [ONLY] and EXECUTE [NOT] PROTECTED in the same
ALTER METHOD request.
SQL Reference: Data Definition Statements
31
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
When you specify COMPILE ONLY, then only the UDM is recompiled and no new dynamic
linked libraries are distributed to database nodes.
See “Restrictions on Altering Methods That Implement UDT Transform and Ordering
Functionality” on page 32 for a description of the restrictions imposed on using ALTER
METHOD to change the protection mode, or to recompile the object code for UDMs that
implement UDT transform or ordering functionality (also see “CREATE ORDERING/
REPLACE ORDERING” on page 455 and “CREATE TRANSFORM/ REPLACE
TRANSFORM” on page 855).
When a UDM is loaded onto another platform of a different type, it is marked as non-valid.
All non-valid UDMs must be recompiled. If there are many UDMs in one database, you can
save time by specifying the ONLY option for all but the last compilation in that database to
avoid having to generate and distribute a new library. When you do this, make certain not to
specify the ONLY option for the last UDM you recompile in that database.
One .dll or .so file is built for all UDMs in each database. The .dll or .so files are
stored outside the database on the system disk of each node. If a .dll or .so file becomes
corrupted on one node, the DBA can regenerate it by issuing an ALTER METHOD statement
with the COMPILE option to rebuild the .dll or .so file.
To regenerate a corrupted .dll, or .so file, you only need to compile one method in that
database. The system regenerates the .dll, or .so file, and includes all other user-defined
methods defined in that database in the regenerated .dll, or .so file.
Note that changing the protection mode for a method also causes the system-generated UDF
constructor function to be recompiled invisibly.11
Restrictions on Altering Methods That Implement UDT Transform and
Ordering Functionality
You cannot use ALTER METHOD to change the protection mode for a method and to request
its recompilation within the same request. You must submit separate requests to do this: one
to alter the execution protection mode and a second to request the recompilation.
If you attempt to request both a change to the execution mode and a recompilation within the
same request, the system returns an error.
Example 1: Changing the Protection Mode
The following ALTER METHOD statement changes the protection mode for the method
named polygon_mbr() from protected to not protected:
ALTER METHOD polygon_mbr() FOR SYSUDTLIB.polygon
EXECUTE NOT PROTECTED;
11. Invisible in that the system does not return any compilation messages unless the compilation fails for some
reason, in which case the system returns an appropriate error message to the requestor.
32
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER METHOD
Example 2: Recompiling a Method Object
The following ALTER METHOD statement recompiles the specific method object named
SYSUDTLIB.polygon_mbr:
ALTER SPECIFIC METHOD SYSUDTLIB.polygon_mbr COMPILE;
Related Topics
The following SQL statements, book chapters, and manuals are related to ALTER METHOD:
•
“ALTER TYPE” on page 142
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE CAST/ REPLACE CAST” on page 184
•
“CREATE METHOD” on page 431
•
“CREATE ORDERING/ REPLACE ORDERING” on page 455
•
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855
•
“CREATE TYPE (Distinct Form)” on page 906
•
“CREATE TYPE (Structured Form)” on page 927
•
“DROP AUTHORIZATION” on page 1001
•
“DROP CAST” on page 1003
•
“DROP ORDERING” on page 1032
•
“DROP TRANSFORM” on page 1041
•
“DROP TYPE” on page 1043
•
“HELP CAST” on page 1427
•
“HELP FUNCTION” on page 1464
•
“HELP METHOD” on page 1493
•
“HELP TRANSFORM” on page 1557
•
“HELP TYPE” on page 1563
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
See Chapter 5: “SQL DCL Syntax,” for information about the UDTTYPE, UDTMETHOD,
UDTUSAGE, and EXECUTE FUNCTION privileges, particularly as described for the
“GRANT (SQL Form)” on page 1199, particularly the topics “UDT-Related Privileges” on
page 1225 and “EXECUTE FUNCTION Privilege” on page 1224.
Also see SQL Reference: UDF, UDM, and External Stored Procedure Programming for
information about how to write user-defined external routines.
SQL Reference: Data Definition Statements
33
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
ALTER PROCEDURE (External Form)
Purpose
Recompiles an existing external stored procedure and allows changes in the following
compile-time attributes of the procedure:
•
Generate a new library for the recompiled procedure or not.
•
Toggle the protection mode between protected and unprotected states.
Syntax
ALTER PROCEDURE
procedure_name
A
database_name.
A
LANGUAGE
C
COMPILE
CPP
;
ONLY
JAVA
EXECUTE
PROTECTED
NOT
1101B284
where:
Syntax element …
Specifies …
database_name
the name of a qualifying database containing the external stored
procedure to be altered.
If database_name is not specified, the default database for the current
session is assumed.
procedure_name
the name of the external stored procedure to be altered. You can alter
only one stored procedure at a time.
LANGUAGE C
that the external procedure is written in the C programming language.
LANGUAGE CPP
that the external procedure is written in the C++ programming
language.
LANGUAGE JAVA
that the external stored procedure is written in the Java programming
language.
Java external stored procedures can only be executed on 64-bit Linux
and Windows systems. You cannot execute a Java external stored
procedure on a UNIX system.
34
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
Syntax element …
Specifies …
COMPILE [ONLY]
that the external procedure is to be recompiled.
IF you specify …
THEN the system recompiles the procedure …
COMPILE
and generates a new library for it.
For Java external procedures, the JAR file
referenced in the EXTERNAL NAME clause is
redistributed to all affected nodes on the
system. This is useful for the case of a missing
JAR file on a given node.
COMPILE ONLY
but does not generate a new library.
For Java external procedures, COMPILE
ONLY generates preamble files, but does not
redistribute their associated JAR file.
EXECUTE PROTECTED
to change the execution mode for the specified external procedure
from unprotected mode to protected mode.
The EXECUTE PROTECTED option causes the external procedure to
execute as a separate process (see “When to Specify Unprotected
Mode” on page 36 for details).
An external stored procedure linked with CLIv2 can only execute in
protected mode.
A Java external stored procedure can only execute in protected mode.
EXECUTE NOT
PROTECTED
to change the execution mode for the specified external procedure
from protected mode to unprotected mode (see “When to Specify
Unprotected Mode” on page 36 for details).
The EXECUTE NOT PROTECTED option causes the external
procedure to execute directly on the Teradata Database.
ANSI Compliance
ALTER PROCEDURE (External Form) is a Teradata extension to the ANSI SQL:2003
standard.
Authorization
To alter an external stored procedure, you must have the ALTER EXTERNAL PROCEDURE
privilege on that procedure or on the database containing the procedure.
Privileges Granted Automatically
None.
SQL Reference: Data Definition Statements
35
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
Invocation Restrictions
Valid for external stored procedures only.
Not valid inside a stored procedure body.
About ALTER PROCEDURE (External Form)
ALTER PROCEDURE (External Form) gives you the ability to control whether an existing
external stored procedure can be executed directly or indirectly as a separate process by
Teradata Database. As a general rule, you should only permit a function to run in direct
execution mode after is has been thoroughly debugged. When you create a new external stored
procedure, it executes indirectly in protected execution mode by default (see “CREATE
PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)” on page 463 for
details).
ALTER PROCEDURE (External Form) also allows you to recompile or relink an external
procedure and redistribute it (and its associated JAR file if the external routine is written in
Java) using the COMPILE option. This option is primarily intended for use by DBAs to
recompile existing procedures that have been moved to another platform, system, or restored
database.
When to Specify Unprotected Mode
To protect the system from new external routines that have not yet passed your quality
metrics, the default execution mode for all external routines is EXECUTE PROTECTED. If the
default specification for CREATE/REPLACE PROCEDURE were EXECUTE NOT
PROTECTED, then an error in the created function could crash the system.
Protected mode is a database state that traps on memory address violations, corrupted data
structures, and illegal computations, such as divide-by-zero, to ensure they do not crash the
system.12 This execution mode isolates all of the data the external routine might access as a
separate process, or “server” in its own local work space (see SQL Reference: UDF, UDM, and
External Stored Procedure Programming for details). If any memory violation or other system
error occurs, then the error is localized to the routine and the transaction executing it, not the
entire database (see “Protected and Unprotected Modes” on page 292 for more information).
Because this isolation also makes the routine run slower, you should change its protection
mode to unprotected once it has passed all your quality metrics for being put into production
use. You change the execution mode for the routine with a simple ALTER PROCEDURE
statement (see “ALTER PROCEDURE (External Form)” on page 34) and specifying the
EXECUTE NOT PROTECTED option.
Do not make this change for any procedure that makes OS system calls. Any such procedure
should always be run in protected mode. You do not need to recompile or relink the external
routine after changing its protection mode.
12. Protected mode does not detect or protect against CPU and memory loops or operating system I/Os such
as opening external files to read from or write to them.
36
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
As a rule, the DBA13 should only specify direct execution mode (assigned by the EXECUTE
NOT PROTECTED option) for a procedure that performs CPU-only operations after it has
been thoroughly debugged. Never run external routines that cause the OS to consume system
resources in unprotected mode.14
The following table summarizes how the external stored procedure protection mode options
should be used:
IF …
THEN specify …
you are still developing and debugging a
procedure
EXECUTE PROTECTED.
the procedure opens a file or uses
another operating system resource that
requires tracking by the operating
systema
EXECUTE PROTECTED.
the procedure is linked with CLIv2 or is
written in Java
EXECUTE PROTECTED.
the procedure is a computational
procedure that does not use any
operating system resources
EXECUTE NOT PROTECTED.
Running such a procedure in unprotected mode could
interfere with the proper operation of the Teradata
Database.
External stored procedures that are linked with CLIv2
can only run in protected mode.
Running an external stored procedure in unprotected
mode speeds up the processing of the function
considerably.
Use this option only after thoroughly debugging the
procedure and making sure it produces the correct
output.
a. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
Stored Procedure Servers
Protected mode external stored procedures, including secure mode procedures, run under a
separate process from the Teradata Database. External procedures set up to require external
security run in a subtype of protected mode called secure mode. The system sets up separate
processes, or servers, to support secure mode procedures (see SQL Reference: UDF, UDM, and
External Stored Procedure Programming for details).
13. No other user than the DBA, not even the software engineer who writes a UDF, should be granted the
privileges to alter it to run in unprotected mode.
14. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
SQL Reference: Data Definition Statements
37
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
The following series of events occurs the first time a secure mode15 external stored procedure
is invoked in a session:
1
The external procedure secure server set-up logic looks at the authorization and
determines whether a secure server process is already set up for the given OS user
authorization.
Because this is the first time the procedure has been invoked in the session, no secure
server process has been set up.
2
The authorization is not set up, so the process validates the OS user by making a validation
check on the user name and password.
For Windows systems, a logon token is obtained.
If the logon attempt using the provided authorization information fails, the system returns
an error to the session.
3
If the authorization is successful, the system creates the secure server process and the
procedure executes.
If this is not the first time the procedure has been executed for the session, the following series
of events occurs:
1
The external procedure secure server set-up logic reads the authorization and determines
that there is already a secure server process set up with that authorization.
2
The procedure is executed using the existing secure server.
If the maximum number of secure servers has been created and a new request comes in for a
given authorization for which there is no established secure server, the following series of
events occurs:
1
The external procedure secure server logic attempts to find a secure server with the given
authorization. It does not find one and determines that the maximum number of secures
servers has already been set up.
2
The authorization is not set up, so the process validates the OS user by making a validation
check on the user name and password.
For Windows systems, a logon token is obtained.
If the logon attempt using the provided authorization information fails, the system returns
an error to the session.
3
The external procedure secure server logic finds the least used secure server process and
terminates it.
4
The new secure server process is created and the procedure is executed.
15. The process is essentially identical for protected mode external stored procedures.
38
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (External Form)
Special Considerations for Java External Stored Procedures
Java external stored procedures can only be run in EXECUTE PROTECTED mode on 64-bit
Linux and Windows platforms.16 If you specify EXECUTE NOT PROTECTED, the request
aborts and returns an error message to the requestor.
For Java external stored procedures, the COMPILE option operates identically to external
procedures written in C or C++ with the exception that the extension the JAR file referenced
in the Java external stored procedure EXTERNAL NAME clause (see “CREATE PROCEDURE
(External Form)/ REPLACE PROCEDURE (External Form)” on page 463) is redistributed to
all affected nodes on the system. Redistribution is useful when a JAR file is missing on a given
node.
The ONLY clause on the COMPILE option for external procedures written in Java generates
preamble files, but does not redistribute their associated JAR file.
Dictionary Updates and the COMPILE Option for Java Procedures
The following dictionary table updates occur as the result of an ALTER PROCEDURE …
COMPILE request for a Java external stored procedure:
1
The corresponding row for a JAR in DBC.TVM is updated with a new version number.
The Platform column in DBC.TVM is also updated.
2
The corresponding row for a JAR in DBC.JARS is updated with a new version number.
3
The corresponding row for the current database in DBC.Dbase is updated with an
incremented JarLibRevision number.
Example 1
This example changes the protection mode of the C-language external stored procedure
named my_xsp from protected to not protected.
ALTER PROCEDURE my_xsp LANGUAGE C EXECUTE NOT PROTECTED;
Example 2
This example recompiles the C-language external stored procedure named my_xsp.
ALTER PROCEDURE my_xsp LANGUAGE C COMPILE;
Related Topics
See the following manual and statements for related information:
•
SQL Reference - Stored Procedures and Embedded SQL
•
“CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)” on
page 463
•
“DROP MACRO/ DROP PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP VIEW”
on page 1027
16. You cannot execute Java external stored procedures on UNIX systems.
SQL Reference: Data Definition Statements
39
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
ALTER PROCEDURE (SQL Form)
Purpose
Recompiles an existing SQL stored procedure and allows changes in the following
compile-time attributes of the procedure:
•
SPL option
•
Warnings option
Syntax
procedure_name
ALTER PROCEDURE
database_name.
COMPILE
A
LANGUAGE SQL
A
,
WITH
;
2
SPL
NO
WARNING
1101S001
NO
where:
Syntax Element …
Specifies …
database_name
the name of a qualifying database containing the stored procedure to be
altered.
If database_name is not specified, the default database for the current session is
assumed.
procedure_name
the name of the stored procedure to be recompiled. You can recompile only
one stored procedure at a time.
LANGUAGE SQL
that the stored procedure body is written in the SQL language.
This clause is optional.
40
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
Syntax Element …
Specifies …
Alter Procedure Options
Optional specifications are stored in the data dictionary with the stored procedure definition. You
can list the options in any order. Each option can be specified at most once.
SPL
that the SQL source text of the stored procedure should be stored in the
dictionary.
NO SPL
that the SQL source text of the stored procedure should not be stored in the
dictionary.
WARNING
that compilation warnings are returned during alteration of the stored
procedure.
NO WARNING
that compilation warnings are not returned during alteration of the stored
procedure.
ANSI Compliance
ALTER PROCEDURE (SQL Form) is a Teradata extension to the ANSI SQL:2003 standard.
Authorization
To alter an SQL stored procedure, you must have either ALTER PROCEDURE or DROP
PROCEDURE privilege on that procedure or on the database containing the procedure.
Privileges Granted Automatically
None.
Invocation Restrictions
Valid for SQL stored procedures only.
Not valid inside a stored procedure body.
Limitations
You cannot use ALTER PROCEDURE to change the DDL definition of an SQL stored
procedure, that is, to REPLACE the procedure.
You cannot use ALTER PROCEDURE to recompile stored procedures created in Teradata
Database V2R4.0 because information about the default database at the time of the stored
procedure creation is not available.
SQL Reference: Data Definition Statements
41
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
Changes Made by ALTER PROCEDURE
ALTER PROCEDURE can alter the following attributes of the recompiled SQL stored
procedure:
•
Platform
•
TDSP version number.
For information about stored procedure version numbers, see “HELP PROCEDURE” on
page 1501.
You can also change one or all of the following attributes:
•
SPL to NO SPL.
You cannot change NO SPL back to SPL.
•
WARNING to NO WARNING and vice versa.
Attributes Not Changed by ALTER PROCEDURE (SQL Form)
The creator and the immediate owner of a stored procedure are not changed after
recompilation.
ALTER PROCEDURE (SQL Form) also does not change the following attributes of the stored
procedure being recompiled:
•
Session mode
•
Creator character set
•
Creator character type
•
Default database
•
The access privileges defined for the stored procedure
ALTER PROCEDURE (SQL Form) Rules
42
•
The stored procedure specified in an ALTER PROCEDURE statement must exist.
•
The stored procedure specified in an ALTER PROCEDURE statement cannot be an
external stored procedure (see “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463).
•
The stored procedure specified in an ALTER PROCEDURE statement must have been
created with the SPL compile-time option. That is, the stored procedure source text must
be available for the stored procedure being recompiled.
•
If a stored procedure is recompiled by an ALTER PROCEDURE statement with NO SPL
option, the source text of the stored procedure is deleted from the system and the stored
procedure cannot be recompiled again.
•
You can alter a stored procedure in the same session mode in which the procedure was
originally created. Stored procedures created in ANSI session mode cannot be recompiled
in Teradata session mode and vice versa.
•
An ALTER PROCEDURE statement cannot be used inside a stored procedure body.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
•
If you do not specify any compile-time options with an ALTER PROCEDURE statement,
the options with which the stored procedure was previously created, replaced, or
recompiled apply. If some compile-time options are specified with an ALTER
PROCEDURE statement, the unspecified options default to the existing options of the
stored procedure.
•
A COMMIT must be specified after an ALTER PROCEDURE statement in ANSI mode
transactions, as in the case of all DDL statements.
•
In Teradata session mode, ALTER PROCEDURE must be the last statement in a
transaction.
•
All the statements other than DML, DDL, and DCL statements within the stored
procedure are validated syntactically and semantically during the execution of an ALTER
PROCEDURE statement.
For DML, DDL, and DCL statements within the stored procedure body, the validation
includes syntactic validation and name resolution but does not include the following:
•
access privilege checks
•
data type compatibility
•
If the execution of an ALTER PROCEDURE statement fails, the existing version of the
stored procedure is retained.
•
Errors or warnings generated during the recompilation of a stored procedure are reported
as part of the SUCCESS or OK response. The activity count in the parcel is set to the total
number of errors and warnings.
Locks and Concurrency
When an ALTER PROCEDURE statement is performed, the system places an EXCLUSIVE
lock on the corresponding stored procedure table in the database. The stored procedure is
unavailable to other users during the recompilation time.
Cross-Platform Recompilation
ALTER PROCEDURE allows recompilation of stored procedures on a new platform after a
cross-platform archive and restore of the database containing the stored procedures.
Normally, stored procedures cannot be used across platforms.
For example, assume that database Alterdb on a Windows system contains a stored procedure
named spAP1, and you want to run spAP1 on a UNIX MP-RAS platform.
To do this, perform the following procedure:
1
Dump database Alterdb from the source Windows system.
2
Log onto the target UNIX MP-RAS system and copy the dump.
3
This step is optional.
Perform the SHOW statement to see the source text of the stored procedure:
SHOW PROCEDURE spAP1;
SQL Reference: Data Definition Statements
43
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
The system returns the following report:
CREATE PROCEDURE spAP1 (in par1 INTEGER, out par2 INTEGER)
BEGIN
SET par2 = par1 * par1;
END;
4
This step is optional.
Perform the HELP PROCEDURE statement to see the platform and other attributes of the
stored procedure.
HELP PROCEDURE spAP1 ATTR;
The system returns the following report:
Transaction Semantics TERADATA
Character Set UTF8
Platform Windows
Collation ASCII
Default Character DataType LATIN
Version Number 03
SPL Text Y
Warning Option Y
Default Database Alterdb
5
This step is optional.
Specify the CALL statement to perform the stored procedure spAP1 on the new platform
(Teradata UNIX MP-RAS).
The request fails with the following message because the object was created in Windows.
*** Failure 5530 Invalid operating environment for procedure
execution.
6
Perform the SQL form of ALTER PROCEDURE to recompile the stored procedure:
ALTER PROCEDURE spAP1 COMPILE;
7
End of procedure.
After the recompilation is completed, you can run HELP PROCEDURE to verify that the
Platform attribute has changed to UNIX MP-RAS.
Using ALTER PROCEDURE (SQL Form): Examples
The first two example make reference to stored procedure spAP2, shown below, to illustrate
the use of ALTER PROCEDURE.
CREATE PROCEDURE spAP2(IN InParam INTEGER,
OUT OutParam INTEGER)
BEGIN
DECLARE Var1 INTEGER DEFAULT 10;
SET OutParam = InParam + Var1 + 1;
END;
The examples assume that the stored procedure has been compiled as follows:
BTEQ> .COMPILE FILE = testsp.spAP2
The SPL option is not specified, but the source text of the stored procedure spAP2 is stored in
the database because SPL is the default.
44
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
Example 1
This example illustrates the use of ALTER PROCEDURE to recompile a stored procedure
created in Teradata Database V2R4.1 with changed options. The example shows that the
original character set of a stored procedure is not changed by ALTER PROCEDURE.
1
Verify the current attributes of the procedure using HELP PROCEDURE.
HELP PROCEDURE spAP2 ATTR;
The system returns the following report:
Transaction Semantics TERADATA
Character Set EBCDIC
Platform UNIX MP-RAS
Collation ASCII
Default Character DataType UNICODE
Version Number 01
SPL Text Y
Warning Option Y
Default Database testsp
The Version Number 01 indicates that the stored procedure was created in Teradata
Database V2R4.1.
2
Using BTEQ, change the session character set from EBCDIC to ASCII:
.SET SESSION charset 'ASCII'
3
Perform ALTER PROCEDURE with the NO SPL and NO WARNING options specified.
ALTER PROCEDURE spAP2 COMPILE WITH NO SPL, NO WARNING;
4
Check the procedure attributes again, after completion of the alteration.
Transaction Semantics TERADATA
Character Set EBCDIC
Platform UNIX MP-RAS
Collation ASCII
Default Character DataType UNICODE
Version Number 03
SPL Text N
Warning Option N
Default Database testsp
Note that the compile-time options are changed as specified, but the character set of the
procedure has not changed. Version Number 03 indicates that the stored procedure has
been upgraded to Teradata Database V2R5.0.
5
End of procedure.
SQL Reference: Data Definition Statements
45
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
Example 2: Failure Case
In this example, ALTER PROCEDURE is performed on a stored procedure originally
compiled with NO SPL option. ALTER PROCEDURE fails because the source text of the
stored procedure is not available for recompiling. The procedure was originally compiled with
NO SPL option; as a result, the source text has not been stored in the database.
1
Compile the stored procedure spAP2.
.COMPILE FILE spAP2.spl WITH NOSPL
2
Verify its attributes.
HELP PROCEDURE spAP2 ATTR;
The system returns the following report:
Transaction Semantics TERADATA
Character Set ASCII
Platform UNIX MP-RAS
Collation ASCII
Default Character DataType UNICODE
Version Number 03
SPL Text N
Print Mode N
Default Database testsp
3
Perform the ALTER PROCEDURE statement.
ALTER PROCEDURE spAP2 COMPILE;
The system returns the following report:
ALTER PROCEDURE spAP2 COMPILE;
*** Failure 5535 No SPL source text available for stored
procedure 'spAP2'.
Since the execution of the ALTER PROCEDURE statement fails, the existing version of the
stored procedure spAP2 is retained.
4
End of procedure.
Example 3: Suppressing Compilation Warnings
This example shows how compilation warnings can be suppressed using the NO WARNING
option of the ALTER PROCEDURE statement by using the following procedure:
1
Create a new stored procedure spAP3.
2
Compile the stored procedure spAP3:
REPLACE PROCEDURE testsp.spAP3 ()
BEGIN
DECLARE var1 INTEGER DEFAULT 10;
SELECT ErrorCode INTO :var1
FROM dbc.errormsgs
WHERE ErrorCode = 5526;
SET var1 = var1 + 1;
END;
BTEQ> .COMPILE FILE spAP3.spl
46
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
The system returns the following report:
*** Procedure has been created 4 Errors/Warnings.
*** Warning: 5527 Stored Procedure Created with Warnings.
*** Total elapsed time was 2 seconds.
.COMPILE FILE spAP3.spl
$
*** SQL Warning 5802 Statement is not ANSI.
Warnings reported during compilation
------------------------------------------------------SPL5000:W(L1), W(5802):Statement is not ANSI.
SPL5000:W(L3), W(5802):Statement is not ANSI.
SPL5000:W(L5), W(5802):Statement is not ANSI.
SPL5000:W(L6), W(5802):Statement is not ANSI.
-------------------------------------------------------
3
Recompile the procedure with NO WARNING option
ALTER PROCEDURE spAP3 COMPILE WITH NO WARNING;
When this statement is successfully performed, the procedure spAP3 is recompiled, but no
compilation warnings are displayed.
4
End of procedure.
Example 4: Impact of Session Mode
This example illustrates the behavior of ALTER PROCEDURE when the session mode is
changed.
The procedure used to do this is as follows:
1
Compile the stored procedure spAP3 in a Teradata session mode session.
BTEQ> .COMPILE FILE spAP3.spl
2
Change the session mode.
.LOGOFF
.SET SESSION TRANS ANSI
.LOGON testsp, password
3
Perform ALTER PROCEDURE.
ALTER PROCEDURE ap3 COMPILE;
The statement fails with the following message:
*** Failure 5510 Invalid session mode for procedure execution.
Statement# 1, Info =0
Since the execution of ALTER PROCEDURE failed, the existing version of the stored
procedure spAP3 is retained.
4
End of procedure.
SQL Reference: Data Definition Statements
47
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER PROCEDURE (SQL Form)
Related Topics
See the following manual and statements for related information:
48
•
SQL Reference - Stored Procedures and Embedded SQL
•
“DROP MACRO/ DROP PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP VIEW”
on page 1027
•
“CREATE PROCEDURE (SQL Form)/ REPLACE PROCEDURE” on page 529
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER REPLICATION GROUP
ALTER REPLICATION GROUP
Purpose
Changes the definition of an existing replication group by adding tables to, or dropping tables
from, the specified group.
Syntax
replication_group_name
ALTER REPLICATION GROUP
A
A
,
;
table_name
ADD
database_name.
,
table_name
DROP
database_name.
,
,
table_name
ADD
database_name.
,
table_name
DROP
database_name.
1101B239
where:
Syntax element …
Specifies …
database_name
the name of the database that contains replication_group_name.
This specification is optional if replication_group_name is contained
within the current database.
replication_group_name
the name of the replication group whose definition is to be changed.
This name must be unique on the system.
The specified replication group must already be defined. If it is not, the
system aborts the request and returns an error to the requestor.
ADD
that the set of table names that follows this keyword is to be added to the
specified replication group definition.
Any table you specify must observe the following rules:
• It must be a base table that is already defined in the system.
• It cannot belong to another replication group.
If you specify both ADD and DROP clauses in the same ALTER
REPLICATION GROUP statement, you must specify all the ADD clauses
before you specify any of the DROP clauses.
SQL Reference: Data Definition Statements
49
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER REPLICATION GROUP
Syntax element …
Specifies …
DROP
that the set of table names that follows this keyword is to be dropped
from the specified replication group definition.
Any table you specify must be an existing member of the replication
group.
If you specify both ADD and DROP clauses in the same ALTER
REPLICATION GROUP statement, you must specify all the ADD clauses
before you specify any of the DROP clauses.
table_name
the name of a table to be added to, or dropped from, the replication
group definition.
ANSI Compliance
ALTER REPLICATION GROUP is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
You must have the REPLCONTROL privilege to alter the definition of a replication group.
Privileges Granted Automatically
None.
Rules for Using ALTER REPLICATION GROUP
The following rules apply to using the ALTER REPLICATION GROUP statement:
•
The replication group you specify must already be defined for the system (see “CREATE
REPLICATION GROUP” on page 626).
•
If you do not specify either an ADD clause set or a DROP clause set, then submitting an
ALTER REPLICATION GROUP statement to the system changes the security token for the
group.
•
If you specify either an ADD clause set, a DROP clause set, or both, then submitting an
ALTER REPLICATION GROUP statement to the system does not change the security
token for the group.
•
If you specify both a set of ADD clauses and a set of DROP clauses, then you must specify
all the ADD clauses before you specify any of the DROP clauses.
You cannot mix ADD and DROP clauses.
•
50
If a change data capture or apply operation has been initiated for the named replication
group, and a table is to be added to the group, then the system sets the state of the table to
Suspended after it is added to the group (see “Replication Group Table States” on
page 639).
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER REPLICATION GROUP
•
The table set to be dropped from the set must be defined currently as members of the
group.
If a table is to be dropped from a replication group, then its state must be one of the
following:
•
Defined
•
Suspended
•
Terminated
Otherwise, the system aborts the request.
•
Any tables added to the replication group should be defined with one of the following
unique constraints in which all columns have also been specified NOT NULL:
•
Unique Primary Index
•
Primary Key
•
Unique Secondary Index
The uniqueness constraint facilitates the ability of the change data apply function to
determine the correct target row for an update or delete operation.
If a table of the replication group is not defined with a unique constraint, then the change
data apply function does not change the data row identifier that was assigned by the server
on which the change data row was generated.
•
The server on which the change row was created and the server to which it is to be applied
must use the same hashing algorithm.
•
The server on which the change row was created and the server to which it is to be applied
must have the same server character set.
•
The source and target tables must have the same column set defined as their primary
index.
•
Because ALTER REPLICATION GROUP is a DDL statement, it follows the general
Teradata Database rule that it must be either the only statement in a transaction or, if there
are other, non-DDL statements defined within the transaction, ALTER REPLICATION
GROUP must be the last statement of the transaction.
Example 1: Adding Tables To and Dropping Tables From a Replication
Group
The following example alters a replication group named receivables_group by adding a table
named payables.invoices and dropping a table named payables.purchorders:
ALTER REPLICATION GROUP receivables_group
ADD payables.invoices,
DROP payables.purchorder;
The security token for receivables_group is not changed as the result of this request.
SQL Reference: Data Definition Statements
51
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER REPLICATION GROUP
Example 2: Changing the Security Token for a Replication Group
The following example changes the security token for a replication group named
receivables_group:
ALTER REPLICATION GROUP receivables_group;
Related Topics
See the following resources for further information about replication services:
52
•
“CREATE REPLICATION GROUP” on page 626
•
“DROP REPLICATION GROUP” on page 1036
•
“SET SESSION OVERRIDE REPLICATION” on page 1165
•
“HELP REPLICATION GROUP” on page 1509
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
•
Database Administration
•
Teradata Replication Solutions Overview
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
ALTER TABLE
Purpose
Performs all the following functions:
•
Adds new attributes for one or more columns of a table or global temporary table
definition.
•
Adds one or more new columns to an existing table or global temporary table definition.
•
Drops one or more columns from a table or global temporary table definition.
•
Modifies column-level and table-level constraints.
•
Modifies referential constraints.
•
Adds or drops the FALLBACK option for a table.
•
Adds or modifies the JOURNAL option for a table.
•
Changes the DATABLOCKSIZE or percent FREESPACE for a table or global temporary
table definition.
•
Changes the LOG and ON COMMIT options for a global temporary table.
•
Changes the name of a column.
•
Modifies the properties of the primary index for a table.
•
Modifies the partitioning properties of the primary index for a table or noncompressed
join index, including modifications to the partitioning expression defined for use by a
partitioned primary index.
•
Regenerates table headers and optionally validates and corrects the partitioning of PPI
table rows.
•
Changes the disk I/O integrity option for a table.
•
Modifies the compression attributes for the columns of a table.
SQL Reference: Data Definition Statements
53
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Basic Table Parameters Modification Syntax
,
table_name
ALTER TABLE
database_name.
A
,
FALLBACK
PROTECTION
NO
WITH JOURNAL TABLE =
table_name
database_name.
JOURNAL
NO
BEFORE
DUAL
ON COMMIT
DELETE
ROWS
PRESERVE
LOG
NO
AFTER JOURNAL
NO
Alter Table
Options
DUAL
LOCAL
NOT LOCAL
CHECKSUM = integrity_checking_level
IMMEDIATE
DEFAULT FREESPACE
FREESPACE = integer
PERCENT
DATABLOCKSIZE = data_block_size
IMMEDIATE
BYTES
KBYTES
KILOBYTES
MINIMUM
DATABLOCKSIZE
MAXIMUM
DEFAULT
54
1101A389
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
,
A
ADD column_name
data type declaration
data type attributes
data type attributes
NULL
NOT
COMPRESS
constant
,
NO
Table
Column
Definition
255
constant
NULL
(
Column
Storage
Attributes
Column
Changes
)
UNIQUE
CONSTRAINT name
PRIMARY KEY
Column
Constraint
Attributes
CHECK
boolean_condition
(
)
table_name
REFERENCES
WITH
CHECK OPTION
ADD
column_name
,
( column_name )
NO
NULL
column_name
DROP
RENAME
old_column_name
ADD
new_column_name
TO
,
AS
FOREIGN KEY ( column_name ) REFERENCES
WITH
CONSTRAINT name
DROP
table_name
CHECK OPTION
NO
,
Reference
Definition
( column_name )
DROP INCONSISTENT REFERENCES
ADD
CHECK
boolean_condition
(
)
column_name
Constraint
Changes
CONSTRAINT name
DROP
CHECK
column_name
MODIFY
CONSTRAINT name
column_name
CHECK
(
boolean_condition
)
CONSTRAINT name
DROP
CONSTRAINT name
,
ADD
UNIQUE
CONSTRAINT name
(
Unique
Definition
column_name )
PRIMARY KEY
1101G034
SQL Reference: Data Definition Statements
55
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Primary Index Modification Syntax
A
NOT PARTITIONED
PARTITION BY
;
partitioning_expression
,
( partitioning_expression (
WITH
DELETE
save_table
INSERT
INTO
,
DROP RANGE
WHERE
15
conditional_expression
#Ln
BETWEEN
B
start_expression
AND
end_expression
EACH
range_size
,
NO RANGE
OR UNKNOWN
,
UNKNOWN
UNKNOWN
B
,
ADD RANGE
BETWEEN
C
start_expression
#Ln
AND
end_expression
range_size
EACH
C
,
WITH
NO RANGE
,
DELETE
save_table
INSERT
OR UNKNOWN
UNKNOWN
INTO
UNKNOWN
,
ADD RANGE
BETWEEN
start_expression
#L1
AND
end_expression
EACH
,
range_size
NO RANGE
OR UNKNOWN
,
,
UNKNOWN
UNKNOWN
1101E112
UNKNOWN
Partitioned Primary Index Revalidation Syntax
table_name
ALTER TABLE
database_name.
REVALIDATE PRIMARY INDEX
A
join_index_name
A
WITH
;
DELETE
save_table
INSERT
INTO
1101A432
56
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Data Type Declarations
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
(fractional_seconds_precision)
WITH TIMEZONE
TIMESTAMP
(fractional_seconds_precision)
WITH TIMEZONE
INTERVAL YEAR
(precision)
TO MONTH
INTERVAL MONTH
(precision)
INTERVAL DAY
TO
(precision)
HOUR
MINUTE
SECOND
( fractional_seconds_precision )
INTERVAL HOUR
TO
(precision)
MINUTE
SECOND
( fractional_seconds_precision )
INTERVAL MINUTE
(precision)
TO SECOND
( fractional_seconds_precision )
INTERVAL SECOND
(precision
)
,fractional_seconds_precision
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
CHAR
( integer )
BYTE
GRAPHIC
( integer )
VARCHAR
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
BINARY LARGE OBJECT
(
integer
BLOB
CHARACTER LARGE OBJECT
(
G
K
M
(
integer
CLOB
(
G
K
M
UDT_name
SYSUDTLIB.
SQL Reference: Data Definition Statements
1101G203
57
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
where:
Syntax Element …
Specifies …
database_name.
table_name
the name of the table to be altered. If database_name is not specified, the
default database for the current session is assumed.
Alter Table Options
The Alter Table options are a Teradata extension to ANSI SQL. The options can be listed in any order.
You cannot modify or revalidate a primary index in the same ALTER TABLE statement you perform to
modify basic table parameters.
FALLBACK
PROTECTION
NO FALLBACK
PROTECTION
WITH JOURNAL TABLE
= database_name.
table_name
to add or remove duplicate copy protection for the table.
If fallback is being added, a duplicate copy of the table is created and stored. If
fallback is being removed, the existing duplicate copy is deleted. The
FALLBACK keyword used alone implies PROTECTION.
a definition for the journal table for the data table being altered. The journal
table table_name need not reside in the same database as the data table.
If a database is not specified, the default database for the current session is
assumed.
If a database is specified, it must exist and table_name must have been defined
as its default journal table.
JOURNAL
the number of before change images to be maintained for the table.
NO BEFORE JOURNAL
If the JOURNAL keyword is specified without NO or DUAL, then a single
copy of the image is maintained unless FALLBACK is in effect or is also
specified.
DUAL BEFORE JOURNAL
If journaling is requested for a table that uses fallback protection, DUAL
images are maintained automatically.
ON COMMIT DELETE
ROWS
the action to take with the contents of a global temporary table when a
transaction ends.
ON COMMIT PRESERVE
ROWS
DELETE ROWS clears the temporary table of all rows.
PRESERVE ROWS retains the rows in the table after the transaction is
committed.
You cannot change the ON COMMIT properties of a global temporary table
if any materialized instance of the table exists anywhere in the Teradata
Database.
LOG
the transaction journaling option for a global temporary table.
NO LOG
LOG maintains a transaction journal for the temporary table during the time
is materialized; NO LOG specifies that no transaction journal is to be kept.
You cannot change the LOG/NO LOG properties of a global temporary table
if any materialized instances of the table exist anywhere in the Teradata
Database.
58
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
NO AFTER JOURNAL
the type of image to be maintained for the table; any existing images are not
affected until the table is updated.
DUAL AFTER JOURNAL
LOCAL AFTER JOURNAL
NOT LOCAL AFTER
JOURNAL
BEFORE JOURNAL
AFTER JOURNAL
The NO and DUAL options specify the number of after-change images to be
maintained for the table.
NOT LOCAL and LOCAL specify whether single after-image journal rows for
non-fallback data tables are written on the same virtual AMP (LOCAL) as the
changed data rows, or on another virtual AMP in the cluster (NOT LOCAL).
the type of image to be maintained for the table. The default for this option is
established by a CREATE DATABASE, CREATE USER, or MODIFY USER
statement for the database in which the table is to be created.
See “CREATE TABLE” on page 648 for a listing of the journaling that results
from the available journal and image type specifications.
DEFAULT FREESPACE
to reset the value for FREESPACE PERCENT to the system default defined for
this table by DBSControl.
This specification does not have an immediate effect on existing cylinders,
but the new attribute value controls any new allocation of cylinder blocks
using this revised free space percentage.
FREESPACE = integer
PERCENT
a new percent of free space to remain on a cylinder after a loading operation
completes.
If the value specified does not fall within the valid range (0 - 75), then an
error is returned. See “FREESPACE” on page 684 for additional information.
This specification does not have an immediate effect on existing cylinders,
but the new attribute value controls any new allocation of cylinder blocks
using this revised free space percentage.
SQL Reference: Data Definition Statements
59
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
integrity_checking_level
a table-specific disk I/O integrity checksum level.
The checksum level setting applies to primary data rows, fallback data rows,
and all secondary index rows for the table.
If you are changing the checksum level for this table to the system-wide
default value, then specify DEFAULT.
You can change the percentage of sampling for the system-wide default values
for LOW, MEDIUM, and HIGH using the Checksum Level Definitions fields
in the DBSControl utility (see Utilities). The values provided here for those
checksum percentages are the defaults specified by the installation or
upgrade.
You cannot change the sampling percentage for the following:
• The system-wide default values ALL and NONE.
• Dictionary tables.
The following table describes the default values for the various checksum
levels:
Level
ALL
DEFAULT
LOW
100
Percentage specified for this table type (see Database
Design) in the Checksum Levels fields of the Disk I/O
Integrity Fields in the DBSControl utility (see Utilities).
2
MEDIUM
33
HIGH
67
NONE
IMMEDIATE
Checksum Sample Count Percentage
Disable checksum disk I/O integrity checks.
that the checksums for all data blocks and cylinder indexes for this table are
to updated immediately.
If you do not specify this option, then data blocks and cylinder indexes are
updated the next time they are updated and written.
60
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
Data Block Size Option
You cannot modify or revalidate a primary index in the same ALTER TABLE statement you perform to
modify basic table parameters.
DATABLOCKSIZE=
data_block_size
[BYTES/KBYTES/
KILOBYTES]
the maximum data block size for blocks that contain multiple rows as the
value data_block_size. The calculation is made in the same manner as the
CREATE TABLE statement.
The value can be expressed either as a decimal or integer number or using
exponential notation. For example, you can write one thousand as either
1000 or 1E3.
BYTES can be abbreviated as BYTE. KILOBYTES can be abbreviated as
KBYTE. This specification is optional.
The maximum data block size value is 127.5 Kbytes.
See Utilities for more detailed information about setting default data block
sizes.
For details about data block size, see “DATABLOCKSIZE” on page 682.
IMMEDIATE
whether to repackage data blocks into the newly specified size immediately or
to wait until an affected block is accessed.
IF the IMMEDIATE option is …
THEN …
specified
the attribute value is changed, but, in
addition, the rows in all existing data
blocks are repacked into data blocks of
the specified size.
not specified
existing data blocks are left unmodified.
In both cases, the new attribute value
will determine the maximum size of
multiple-row data blocks subsequently
modified or allocated.
See “IMMEDIATE DATABLOCKSIZE” on page 77.
MINIMUM
DATABLOCKSIZE
the smallest possible DATABLOCKSIZE setting for the table.
The value can be expressed either as a decimal or integer number or using
exponential notation. For example, you can write one thousand as either 1000
or 1E3.
MINIMUM DATABLOCKSIZE sets the maximum data block size for blocks
that contain multiple rows to the minimum legal value of either 6144 or 7168
bytes (12 or 14 sectors), depending on the cylinder size set for your system.
See “DATABLOCKSIZE” on page 682.
SQL Reference: Data Definition Statements
61
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
MAXIMUM
DATABLOCKSIZE
the largest possible DATABLOCKSIZE setting for the table.
The value can be expressed either as a decimal or integer number or using
exponential notation. For example, you can write one thousand as either 1000
or 1E3.
MAXIMUM DATABLOCKSIZE sets the maximum data block size for blocks
that contain multiple rows to the maximum legal value of 130,560 bytes (255
sectors).
DEFAULT
DATABLOCKSIZE
the default DATABLOCKSIZE setting for the table.
The value can be expressed either as a decimal or integer number or using
exponential notation. For example, you can write one thousand as either 1000
or 1E3.
See Utilities for information about setting system-wide default data block
sizes.
For details about data block sizes, see “DATABLOCKSIZE” on page 682.
Column Change Options
You cannot modify or revalidate a primary index in the same ALTER TABLE statement you perform to
modify basic table parameters.
ADD column_name
to add or change the specified column and its specified attributes.
data_type_declaration
ADD and DROP cannot both be specified on the same column in the same
ALTER TABLE statement.
data_type_attributes
column_storage_attributes
column_constraint_
attributes
The ADD keyword either changes the definition of an existing column or
adds a new column to the table. If the named column already exists, ADD
indicates that its attributes are to be changed.
column_name specifies the name of a column whose attributes are to be
changed or that is to be added.
You must always specify a data type for a newly added column.
If you do not specify explicit formatting, a new column assumes the default
format for the data type, which can be specified by a custom data formatting
specification (SDF) defined by the tdlocaledef utility (see Utilities). Explicit
formatting applies both to the parsing and to the retrieval of character
strings.
You cannot add an identity column to an existing table, nor can you add the
identity column attribute to an existing column.
Data types and data type attributes are the subject of SQL Reference: Data
Types and Literals. Column storage and constraints attributes are described in
“Column and Table Constraints” in that volume.
You can add compression to a set of existing columns whether or not the
table is empty or filled with data.
62
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
COMPRESS
a specified set of distinct values in a column that is to be compressed to zero
space.
The default is to compress nulls only.
See Database Design for a detailed description of value compression.
See SQL Reference: Data Types and Literals for more information about the
COMPRESS attribute.
NULL
that nulls are compressed.
The following rules apply:
• You cannot specify NULL if the column is defined as NOT NULL.
• UDTs and variable length data types such as VARCHAR, VARBYTE, and
VARGRAPHIC cannot be compressed.
• You can only specify NULL once per column.
constant
that nulls and the value are compressed.
You cannot compress nulls and constants if the column is defined as NOT
NULL.
Using COMPRESS on fixed-length character data can save space depending
on the percentage of rows for which the compressed value is assigned.
See SQL Reference: Data Types and Literals for information about limits for
this value.
NO COMPRESS
that the specified column is not compressible.
This is the default.
If you specify NO COMPRESS for an existing column defined with
compression, then the compression attribute is dropped for the column.
ADD column_name NULL
to change an existing column column_name from being NOT NULL to being
nullable.
This option is a Teradata extension to the ANSI standard.
DROP column_name
that the named column is to be removed from the table.
You can drop an identity column from an existing table, but you cannot drop
just the identity column attribute and retain the column.
You cannot drop the QITS column from a queue table (see “CREATE TABLE
(Queue Table Form)” on page 817).
RENAME
old_column_name
the name of a column that is to be renamed as new_column_name.
[AS] TO
new_column_name
the new name for the column named in old_column_name.
SQL Reference: Data Definition Statements
Note that you can rename a column and then add a new column to the same
table using the old name for the renamed column. Of course if you do this,
you must rename the old column before creating a new column that uses the
previous name for the renamed column (see “Example 16: Renaming a
Column, Then Adding a New Column Using the Previous Name of the
Renamed Column” on page 124).
63
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
Constraint Change Options
You cannot modify or revalidate a primary index in the same ALTER TABLE statement you perform to
modify basic table parameters.
ADD/DROP
CONSTRAINT name
FOREIGN KEY
(column_name_list)
REFERENCES
table_name column_name
to add or drop a named constraint.
WITH CHECK OPTION
that the constraint added or dropped is a standard referential integrity
constraint for which the integrity of the relationship is checked only when the
entire transaction of which it is a component completes.
You cannot add either of the following constraints to a queue table definition:
• REFERENCES
• FOREIGN KEY … REFERENCES
If any of the rows in the transaction is found to violate the Referential
Integrity rule, then the entire transaction is rolled back.
This clause is a Teradata extension to the ANSI SQL:2003 standard.
WITH NO CHECK
OPTION
that the constraint added or dropped is not to be used to validate referential
integrity.
This clause can only be specified with a table-level FOREIGN KEY …
REFERENCES … constraint or a column-level REFERENCES … constraint.
This clause is a Teradata extension to the ANSI SQL:2003 standard.
DROP INCONSISTENT
REFERENCES
to delete all inconsistent references defined on the table.
DROP INCONSISTENT REFERENCES is commonly used after a restore,
when an ALTER TABLE DROP FOREIGN KEY might not work.
This clause is a Teradata extension to the ANSI SQL:2003 standard.
ADD CHECK
(boolean_ condition)
ADD column_name
CHECK
(boolean_ condition)
ADD CONSTRAINT name
CHECK
(boolean_ condition)
You cannot add CHECK constraints on LOBs nor can you add CHECK
constraints that reference LOBs.
When a constraint is added or modified, all existing rows of the table are
scanned to validate that the current values conform to the specified search
condition. If not, an error is returned and no change is made to the table
definition.
This clause is a Teradata extension to the ANSI SQL:2003 standard.
DROP CHECK
to drop all unnamed column-level CHECK constraints on column_name.
DROP column_name
CHECK
DROP CHECK drops the unnamed table-level constraints on the table.
DROP CONSTRAINT
name CHECK
64
to add or modify a constraint condition.
DROP column_name CHECK drops column-level constraints on the
specified column.
DROP CONSTRAINT name CHECK or DROP CONSTRAINT name drop a
named table-level CHECK constraint on the table.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
MODIFY column_name
CHECK
(boolean_condition)
to modify a check constraint, whether named or unnamed.
MODIFY CONSTRAINT
name CHECK
(boolean_condition)
This also includes the named constraints defined as part of the column
definition since those constraints are handled as named table-level
constraints. MODIFY column_name CHECK is allowed only if
column_name already has a defined constraint.
MODIFY CONSTRAINT name CHECK (boolean_condition) is valid only if a
constraint with name already exists in the table.
Existing rows of the table are scanned to validate that the current values
conform to the specified search condition. If not, an error is returned and no
change is made to the table definition.
DROP CONSTRAINT
name
to drop a table-level named constraint on the stated table.
ADD column_name
[CONSTRAINT name]
UNIQUE
to add a uniqueness constraint on one or more columns of the table.
The columns listed for uniqueness must all be defined to be NOT NULL.
You cannot add uniqueness constraints on LOBs.
ADD column_name
[CONSTRAINT name]
PRIMARY KEY
Supported uniqueness constraints are the following:
• UNIQUE
• PRIMARY KEY
Existing rows are scanned to validate that the proposed uniqueness constraint
is not violated.
If uniqueness is violated, an error is reported and no change is made.
The system implicitly creates a unique secondary index on any column set
specified as UNIQUE or PRIMARY KEY.
MODIFY PRIMARY INDEX Option
You cannot modify basic table parameters or revalidate a primary index in the same ALTER TABLE
statement you perform to modify a primary index. See “General Rules for the Primary Index Options
Clause” on page 101 and “General Rules for the MODIFY PRIMARY INDEX Option” on page 102.
MODIFY [[NOT]
UNIQUE] PRIMARY
INDEX (column_name)
to change the uniqueness property of the primary index for the table.
To change a nonunique primary index to a unique primary index, specify
MODIFY UNIQUE PRIMARY INDEX.
To change a unique primary index to a nonunique primary index, specify
MODIFY NOT UNIQUE PRIMARY INDEX.
index_name
NOT NAMED
to change whether the primary index for the table is named or unnamed or to
change the name of a named primary index.
To name an unnamed primary index or change the existing name of a
primary index to something else, specify MODIFY … PRIMARY INDEX
index_name.
To drop the name of a named index, specify MODIFY … PRIMARY INDEX
NOT NAMED.
SQL Reference: Data Definition Statements
65
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
NOT PARTITIONED
to change whether the primary index for the table is partitioned or not or to
change the partitioning expression for an existing partitioned primary index.
PARTITION BY
partitioning_expression |
You cannot specify LOB partitioning columns.
To change a partitioned primary index to a nonpartitioned primary index,
specify NOT PARTITIONED.
To change a nonpartitioned primary index to a partitioned primary index, or
to change the partitioning expression for an existing partitioned primary
index, specify PARTITION BY and then specify a valid partitioning
expression (see “Rules For Altering the Partitioning Expression For a Primary
Index” on page 108).
WITH DELETE
to delete any row whose partition number evaluates to a value outside the
valid range of 1 - 65,535, inclusive.
WITH INSERT [INTO]
save_table
to insert any row whose partition number evaluates to a value outside the
valid range of 1 - 65,535, inclusive, into the table named by save_table.
save_table and the table being altered must be different tables.
DROP RANGE [#Ln]
WHERE
conditional_expression
to use a conditional expression to drop a range set from the RANGE_N
function on which the partitioning expression for the table is based.
#Ln represents a partition level number where n is an integer between 1 and
15, inclusive.
You can only drop ranges if the partitioning expression for the table is derived
exclusively from a RANGE_N function.
You must base conditional_expression on the system-derived PARTITION
column or PARTITION#Ln column set, where the value for n depends on the
level being modified and whether one or multiple levels are changed (see
“Rules for Altering the Partitioning Expression for a Multilevel Partitioned
Primary Index” on page 110 for details).
See SQL Reference: Functions and Operators for details about the RANGE_N
function.
DROP RANGE [#Ln]
BETWEEN start_expression
AND end_expression
EACH range_size [NO
RANGE [OR
UNKNOWN]]
to drop a set of ranges from the RANGE_N function on which the
partitioning expression for the table is based.
#Ln represents a partition level number where n is an integer between 1 and
15, inclusive.
The expressions start_expression and end_expression are defined using the
RANGE_N function (see SQL Reference: Functions and Operators for details).
The expressions must not have a BLOB, CLOB, or BIGINT data type.
The range_size variable must be a constant expression.
You can also drop NO RANGE OR UNKNOWN and UNKNOWN
specifications from the definition for the RANGE_N function.
You can only drop ranges if the partitioning expression for the table is derived
exclusively from a RANGE_N function.
Ranges must be specified in ascending order.
66
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Syntax Element …
Specifies …
ADD RANGE [#Ln]
BETWEEN start_expression
AND end_expression
EACH range_size [NO
RANGE [OR
UNKNOWN]]
to add a set of ranges to the RANGE_N function on which the partitioning
expression for the table is based.
#Ln represents a partition level number where n is an integer between 1 and
15, inclusive.
The expressions start_expression and end_expression are defined using the
RANGE_N function (see SQL Reference: Functions and Operators for details).
The expressions must not have a BLOB, CLOB, or BIGINT data type.
The range_size variable must be a constant expression.
You can also add NO RANGE OR UNKNOWN and UNKNOWN
specifications to the definition for the RANGE_N function.
You can only add ranges if the partitioning expression for the table is derived
exclusively from a RANGE_N function.
Ranges must be specified in ascending order.
WITH DELETE
to delete any row whose partition number is null or evaluates to a value
outside the valid range of 1 - 65,535, inclusive.
WITH INSERT [INTO]
save_table
to insert any row whose partition number is null or evaluates to a value
outside the valid range of 1 - 65,535, inclusive, into the table named by
save_table.
save_table and the table being altered must be distinct.
REVALIDATE PRIMARY INDEX Option
You cannot modify either the basic table parameters or the primary index in the same ALTER TABLE
statement you perform to revalidate a primary index. See “General Rules for the Primary Index Options
Clause” on page 101 and “Rules For Altering the Partitioning Expression For a Primary Index” on page 108.
REVALIDATE PRIMARY
INDEX
to regenerate the table headers for a specified table or noncompressed join
index with a partitioned primary index.
You can optionally verify row partitioning and correct any errors that are
found during the verification process by specifying either the WITH DELETE
or WITH INSERT [INTO] save_table options.
WITH DELETE
to delete any row encountered during revalidation whose partition number
evaluates to a value outside the valid range of 1 - 65,535, inclusive.
WITH INSERT [INTO]
save_table
to insert any row encountered during revalidation whose partition number
evaluates to a value outside the valid range of 1 - 65,535, inclusive, into the
table named by save_table.
save_table and the table being altered must be distinct. You cannot insert rows
with nonvalid partitions into a regular Teradata Database base table.
ANSI Compliance
ALTER TABLE is ANSI SQL:2003-compliant with extensions.
SQL Reference: Data Definition Statements
67
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Authorization
To alter a table, you must have DROP TABLE privilege on that table or on the database
containing the table.
You must have either of the following privileges to add a UDT column to a table or to drop a
UDT column from a table:
•
UDTUSAGE privilege on the specified UDT.
•
At least one of the following privileges on the SYSUDTLIB database:
•
UDTUSAGE
•
UDTTYPE
•
UDTMETHOD
Privileges Granted Automatically
ALTER TABLE … ADD CONSTRAINT, where the added constraint is a referential integrity
constraint, grants the following privileges automatically to the requestor adding the RI
constraint:
•
DELETE on the error table for the constraint
•
DROP TABLE on the error table for the constraint
•
INSERT on the error table for the constraint
•
SELECT on the error table for the constraint
•
UPDATE on the error table for the constraint
No privileges are granted automatically for any other ALTER TABLE option.
Rules for Number of Changes Made in One ALTER TABLE Statement
The rules for number of changes that can be made within a single ALTER TABLE statement
are as follows:
•
Only one change can be made per column per ALTER TABLE statement.
•
Only one CHECK alteration is permitted per ALTER TABLE statement, and you cannot
mix CHECK and non-CHECK alterations on the same table for the same ALTER TABLE
statement.
Rules for Modifying Queue Tables
There are a number of restrictions on queue tables, as detailed in the following list:
68
•
You cannot change a queue table into a non-queue table.
•
You cannot modify the first column defined for a queue table to be something other than a
user-defined QITS column (see “QITS Column” on page 832).
•
You cannot drop the QITS column from a queue table.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
You cannot modify the QITS column by adding either of the following attributes:
•
UNIQUE
•
PRIMARY KEY
Because of this restriction, you cannot add a simple UPI on the QITS column.
Similarly, you cannot modify the QITS column to make it a simple UPI.
•
You cannot add either of the following constraints to a queue table definition:
•
FOREIGN KEY … REFERENCES
•
REFERENCES
•
You cannot modify any column of a queue table to have a LOB data type (see SQL
Reference: Data Types and Literals).
•
You cannot add a permanent journal to the definition for a queue table.
•
You cannot add a reference to queue table columns in a REFERENCES clause for any table.
Otherwise, all column- and table-level constraint clauses are valid within queue table
definitions with the exception of UNIQUE and PRIMARY KEY constraints not being valid
attributes for the QITS column.
•
You cannot modify a queue table definition to have a partitioned primary index.
Rules for Modifying Data Tables Defined With an Error Table
Several rules apply to altering a table that is associated with an error table (see “CREATE
ERROR TABLE” on page 205).
The system maintains the compatibility between data tables and their associated error tables
by disallowing any of the operations in the following list when an error table is defined for a
data table:
•
•
You cannot make any of the following changes to a data table definition if the table is
associated with an error table:
•
Add a column
•
Drop a column
•
Alter its primary index
•
Change its fallback protection
You can modify the partitioning of a PPI data table that has an associated error table.
Rules for Modifying Error Tables
You cannot use the ALTER TABLE statement to change the definition of an error table in any
way, including changing its fallback properties, changing its table type from the default
MULTISET to a SET table type, and changing its primary index from an NPPI to a PPI.
SQL Reference: Data Definition Statements
69
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Rules for Large Object Data Types
The Teradata Database supports the following large object (LOB) data types:
•
Binary large object (BLOB)
•
Character large object (CLOB)
The rules for specifying these types in an ALTER TABLE statement are different from the rules
that apply to other data types. Rules for specifying LOB data types in an ALTER TABLE
statement are as follows:
•
You can increase the maximum size for a LOB column definition, but you cannot decrease
that size.
•
You can only alter the following column attributes:
•
NULL
•
NOT NULL17
•
TITLE
•
FORMAT
If you change the tdlocaledef.txt file and issue a tpareset command, the new format
string settings affect only those tables that are created after the reset. Existing table
columns continue to use the existing format string in DBC.TVFields unless you submit
an ALTER TABLE request to change it.
•
You can add LOB columns to a maximum of 32 per base table definition.
•
If a table already has 32 LOB columns, you cannot add another LOB column to it using the
same ALTER TABLE statement that drops one of the 32 existing LOB columns.
Instead, you must drop an existing LOB column with one ALTER TABLE statement and
then add the new LOB column using a separate ALTER TABLE statement.
•
You can drop LOB columns from a base table.
If you drop all LOB columns from a base table, that table is no longer bound to any LOB
restrictions.
•
A constraint definition can neither be defined for nor reference a LOB column.
•
You cannot specify expressions or referenced columns with BLOB or CLOB data types in a
start or end expression for a primary index range.
17. You cannot change the attribute from NULL to NOT NULL if there are nulls in any rows in the table for
that column.
70
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
ALTER TABLE Support For UDTs
You can use ALTER TABLE to do any of the following things with UDT columns:
•
Add a UDT column to a table.
A LOB UDT column counts as one LOB column even if the UDT is a structured type with
multiple LOB attributes. The limit of 32 LOB columns includes both predefined type LOB
columns and LOB UDT columns.
Note: A UDT must have both its ordering and its transform functionality defined before
you can add a column typed with that UDT to a table definition.
If you attempt to add such a column to a table definition without first defining its ordering
and transform characteristics, the system aborts the request and returns an error to the
requestor.
Be aware that each UDT column you add to a table definition subtracts approximately 80
bytes from the available space in the table header. The total number of UDT columns that
can be defined for a table is dependent on the presence of other features that also consume
space in the table header such as indexes, compression, and so on.
In the absence of any other optional features that occupy table header space, the upper
limit on the number of UDT columns that can be defined, assuming a fat table header is
approximately 1600 columns. See Database Design for information about thin and fat table
headers and the respective table header space taken up by various database features.
•
Drop a UDT column from a table.
•
Modify the attributes of a UDT column.
You can only modify the following set of attributes for a UDT column:
•
[NOT] NULL
•
FORMAT
The FORMAT string must be valid for the external type of the UDT (see “CREATE
TRANSFORM/ REPLACE TRANSFORM” on page 855).
If you do not specify a format explicitly, the system applies the default display format of
the external data type.
•
TITLE
•
NAMED
•
DEFAULT NULL
SQL Reference: Data Definition Statements
71
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
•
•
You cannot modify the following attributes for UDT columns because they are not
supported for UDT columns:
•
DEFAULT numeric_value
•
USER
•
DATE
•
TIME
•
UPPERCASE
•
CASESPECIFIC
•
WITH DEFAULT
•
CHARACTER SET
•
COMPRESS
•
PRIMARY KEY
•
UNIQUE
•
[CHECK] CONSTRAINT
You cannot modify a table to have a column attributed with any of the following set of
constraints to reference a UDT column:
•
[CHECK] CONSTRAINT
•
FOREIGN KEY
•
REFERENCES
If a table has a PPI, its partitioning expression cannot reference UDT columns.
Recommended Null Handling Technique For UDT Columns
If you intend to support null attributes or if you write a map ordering routine that can return
nulls, then any CREATE TABLE or ALTER TABLE statements that specify that type should
specify the NOT NULL attribute for that UDT column.
This is because if nulls are permitted in the column and either the map ordering routine or the
system-generated observer method for the UDT can return nulls, then a situation exists that is
somewhat analogous to the situation in which queries are executed against a column
attributed as NOT CASESPECIFIC. In this situation, for specific queries, the results returned
for identical requests can vary from query to query. The ordering routine for a UDT
determines whether or not column values are equal and also determines the collation order
for sort operations.
If you do not follow this recommendation, then it is possible for the following things to be
treated equally:
•
A column null.
•
A structured type that contains null attributes and whose map or observer routine returns
nulls.
In other words, sometimes a column null is returned in the result set and other times the nonnull structured type that contains null attributes is returned in the result set.
72
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
The following simple example indicates how you should specify the NOT NULL attribute for
UDT columns in a table definition:
CREATE TABLE udtTable (
id
INTEGER,
udtColumn myStructUdtWithNullAttributes NOT NULL);
FALLBACK and JOURNAL Defaults
The FALLBACK and JOURNAL defaults for a base table are originally determined by the
statement that created or modified the object in which the table resides (see “CREATE
TABLE” on page 648, “CREATE DATABASE” on page 198, and “MODIFY USER” on
page 1086).
Either or both of these defaults can be overridden by the statement that created the base table
(see “CREATE TABLE” on page 648) or by the ALTER TABLE statement.
ALTER TABLE Cannot Be Used for Volatile Tables
You cannot use ALTER TABLE to change the definition for a volatile table. Instead, you must
DROP the old table and CREATE a new one to replace it.
Locks and Concurrency
When an ALTER TABLE statement is performed, an EXCLUSIVE lock is placed on the base
table being altered.
Because of the overhead required to alter a base table for dropped or added columns, you
should establish a final form for the table before it contains very many rows. When a very large
table is altered, it can be unavailable to other users for a long time.
ALTER TABLE and FALLBACK
When an ALTER TABLE statement adds FALLBACK, a full-table scan is generated. To add
FALLBACK to a table, all AMPs must be online and operational.
You can change the FALLBACK properties of a global temporary table definition if and only if
there are no materialized instances of that table anywhere in the system.
However, when an instance of a global temporary table is materialized, the system creates it
without fallback irrespective of its definition unless there is a down AMP in the system. In that
case, and that case only, the table is materialized with fallback if it has been defined to do so.
SQL Reference: Data Definition Statements
73
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Disk I/O Integrity Checking
The Teradata Database permits you to select various levels of disk I/O integrity checking of
your table data using one of the following integrity checks ranked in order of their ability to
detect errors:
1
Full end-to-end checksums (ALL option)
Detects most bit, byte, and byte string errors.
2
Statistically sampled partial end-to-end checksums (LOW, HIGH, or MEDIUM options)
Detects lost writes and intermediate levels of bit, byte, and byte string errors.
3
Disable checksum disk I/O integrity checks (NONE option)
Detects some forms of lost writes using standard file system metadata verification.
The checksum setting applies to primary data rows, fallback data rows, and all secondary
index rows for the table.
You cannot change the checksum level of a dictionary table using ALTER TABLE.
This feature detects and logs disk I/O errors: it does not fix them.
The more words used to generate the checksum value, the better able that checksum is to
detect disk I/O errors. Because CPU utilization increases as a function of the number of words
used to generate a checksum, several different levels of checking are provided so you can
adjust disk I/O integrity checking at the level of individual tables as needed, balancing
integrity checking against system performance.
To update the checksum values for all table data blocks and cylinder indexes immediately,
specify the IMMEDIATE option. Otherwise, the system only enables checksums gradually as
each DB in the table is updated and written to disk. Future writes for the table then create and
generate checksums for new and modified data blocks automatically, but unmodified DBs
would never have checksums enabled for them.
The following applications are the most common uses for the IMMEDIATE option:
•
To turn checksums off for the table.
•
To begin checksums immediately when disk array problems have been detected.
You can specify system-wide checksum defaults for various table types using the Checksum
Levels fields of the DBSControl utility Disk I/O Integrity fields and you can specify the
system-wide checksum level definitions for the LOW, MEDIUM, and HIGH values using the
Checksum Level Definitions fields of the DBSControl utility Disk I/O Integrity fields. See
Utilities and Database Administration for details.
74
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Dropping Columns From a Table
When a column is dropped, the system must delete the field corresponding to the dropped
column in every row in the table.
Indexed columns cannot be dropped without first dropping the index on those columns. If an
attempt is made to drop a column on which a primary, secondary, hash, or join index is
defined, an error message is returned.
Columns referenced in the UPDATE OF clause of a trigger cannot be dropped.
You can drop an identity column from an existing table, but you cannot drop just the identity
column attribute and retain the column.
You can drop LOB columns from a base table without restraint. If you drop all the LOB
columns from a table, it is no longer bound to any LOB restrictions (see “Rules for Large
Object Data Types” on page 70).
You cannot drop the QITS column from a queue table.
You cannot drop a partitioning column for a PPI without first modifying the partitioning to
exclude that column from the partitioning set. If you attempt to drop a partitioning column,
the system returns an error.
The following procedure explains what you must do to drop a column on which an index is
defined:
To drop a column on which this
type of index is defined …
Primary: the table has no
rows.
Follow this procedure …
1 Use the primary index modification syntax of the ALTER
TABLE statement to modify the table definition to create a
new primary index.
2 Use ALTER TABLE table_name DROP column_name to drop
the column set that was the former primary index.
3 End of procedure.
Primary: using the CREATE
TABLE AS statement
1 Copy the table into a newly defined table defined with a
different primary index using the CREATE TABLE AS syntax
(see “CREATE TABLE (AS Clause)” on page 750).
2 Drop the original table (see “DROP MACRO/ DROP
PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP
VIEW” on page 1027).
3 Rename the new table (see “RENAME MACRO/ RENAME
PROCEDURE/ RENAME TABLE/ RENAME TRIGGER/
RENAME VIEW” on page 1109).
4 End of procedure.
SQL Reference: Data Definition Statements
75
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
To drop a column on which this
type of index is defined …
Primary: legacy method
Follow this procedure …
1 Create a new table with the correct primary index (see
“CREATE TABLE” on page 648).
2 Copy the data into the new table.
A simple way to do this is to use an INSERT … SELECT
statement (see “INSERT … SELECT” in SQL Reference:
Data Manipulation Statements).
3 Drop the original table (see “DROP MACRO/ DROP
PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP
VIEW” on page 1027).
4 Rename the new table (see “RENAME MACRO/ RENAME
PROCEDURE/ RENAME TABLE/ RENAME TRIGGER/
RENAME VIEW” on page 1109).
5 End of procedure.
1 Drop the index (see “DROP INDEX” on page 1020).
• Secondary
• Hash
• Join
2 Drop the index columns.
3 Define a new index on the correct columns (see “CREATE
INDEX” on page 336).
4 End of procedure.
Adding Columns To a Table
When a column is added to a base table that already contains data, the system generally needs
to access each row of the table to add a field for the new column. The following principles
apply when adding a column to a base table that already contains rows:
IF this phrase …
IS …
THEN all rows initially …
DEFAULT
specified for the new column
contain the specified constant values in the field.
WITH
DEFAULT
specified for the new column
contain the system default in the field.
DEFAULT
not specified for the new
column
are null for the field, and the NOT NULL phrase
cannot be specified for the column.
WITH
DEFAULT
A column that is defined as NOT NULL can only be added to an empty base table if it has no
DEFAULT or WITH DEFAULT phrase.
You cannot change the data type, nullability, or name of a partitioning column for a PPI.
You cannot change the data type, nullability, or name of an indexed column.
76
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
You cannot add an identity column to an existing base table, nor can you add the identity
column attribute to an existing column.
You can add LOB columns to a maximum of 32 per base table (see “Rules for Large Object
Data Types” on page 70).
Renaming Table Columns
You can rename table columns within certain restrictions.
Renaming is rejected when any of the following is true:
•
new_column_name matches any existing column name in the target table.
•
the affected column is an index field.
•
the affected column is part of any type of referential constraint.
•
the affected column is a partitioning column for a partitioned primary index.
•
the affected column is referenced in the UPDATE OF clause of a trigger.
DEFAULT FREESPACE
At any give time, the FREESPACE value returned in response to a SHOW TABLE statement is
the value specified in the most recently entered ALTER TABLE or CREATE TABLE statement.
See “CREATE TABLE” on page 648 and “SHOW CAST/ SHOW ERROR TABLE/ SHOW
FUNCTION/ SHOW HASH INDEX/ SHOW JOIN INDEX/ SHOW MACRO/ SHOW
METHOD/ SHOW PROCEDURE/ SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW
TRIGGER/ SHOW TYPE/ SHOW VIEW” on page 1590 for more information.
DEFAULT FREESPACE has the following properties:
•
Specifying the DEFAULT FREESPACE option when the percent freespace has been
previously set to a value other than the default value resets the size to the system default
value.
•
If the FREESPACE option is not included in the ALTER TABLE statement, then the
percent freespace attribute value is not changed.
IMMEDIATE DATABLOCKSIZE
The only reason to change the data block size for a table is to enhance performance. Repacking
the data blocks of large tables is a time-consuming process, so specifying the IMMEDIATE
option for large tables substantially increases the amount of time required for the ALTER
TABLE statement to complete.
Field upgrades of systems do not change the data block size from 64 Kbyte to 127.5 Kbyte
until a block splits. To take immediate advantage of the performance enhancements offered by
the 127.5 Kbyte block size, you must force the data block size change directly.
SQL Reference: Data Definition Statements
77
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
To upgrade the data block size from 63.5 Kbyte to 127.5 Kbyte, perform one of the following
ALTER TABLE statements on every table in every database:
ALTER TABLE database_name.table_name, DEFAULT DATABLOCKSIZE
IMMEDIATE;
ALTER TABLE database_name.table_name, DATABLOCKSIZE = 127.5 KBYTES
IMMEDIATE;
If you do not specify the IMMEDIATE keyword, the definition for DATABLOCKSIZE is set to
127.5 Kbytes, but the size increase does not occur until rows are inserted into the newly
defined table.
Because of the extra time required to process statements with the IMMEDIATE option, you
should plan to convert your data block sizes during non-peak hours.
When an ALTER TABLE statement with the IMMEDIATE option aborts or is aborted by the
user, the repacking might be incomplete; that is, some data blocks are of their original size,
while others are of the newly specified size.
At any given time, the DATABLOCKSIZE value returned in response to a SHOW TABLE
statement is the value specified in the most recently entered ALTER TABLE or CREATE
TABLE statement.
If no DATABLOCKSIZE specification is specified in the ALTER TABLE statement, then the
data block size is not changed and no data blocks are repacked.
Journaling
Journaling supports rollback and back up operations.
To preserve the restore capability of journaling, changing only journaling options with ALTER
TABLE retains the version number of the table. Other ALTER TABLE options change the
structure of tables and thus require incrementing the table version number.
The journaling options include:
•
WITH JOURNAL TABLE
•
JOURNAL
•
AFTER JOURNAL
Activating Permanent Journaling
If a table is created in a database that does not have permanent journaling activated, you can
activate its journaling with ALTER TABLE. To do this, you must alter the table to include a
journaling option such as AFTER JOURNAL or BEFORE JOURNAL or both. As soon as the
ALTER TABLE statement completes successfully, permanent journaling is activated for that
table.
See “Example 3: Add a Single Before-Image Journal and Dual After-Image Journal” on
page 121 for an example of how to activate permanent journaling for a table.
78
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
To determine which tables in your Teradata Database are journal tables, use the following
query:
SELECT DBC.dbase.databasename (FORMAT 'X(15)'),
DBC.tvm.tvmname (FORMAT 'X(25)')
FROM DBC.tvm,DBC.dbase
WHERE DBC.dbase.databaseid=DBC.tvm.databaseid
AND
DBC.tvm.tablekind='j'
ORDER BY 1,2;
To determine which databases and users in your Teradata Database currently have a default
journal table defined for them, use the following query:
SELECT d.databasename (TITLE'Database'),TRIM(dx.databasename)
||'.'||TRIM(t.tvmname)(TITLE 'Journal')
FROM DBC.dbase d
,DBC.TVM
t
,DBC.dbase dx
WHERE d.journalid IS NOT NULL
AND
d.journalid <> '00'xb
AND
d.journalid = t.tvmid
AND
t.databaseid = dx.databaseid
ORDER BY 1;
To determine which tables in your Teradata Database are currently being journaled, use the
following query:
SELECT TRIM(Tables_DB)||'.'||TableName (TITLE 'Table',
CHARACTER(26)),'Assigned To' (TITLE ' '),TRIM(journals_db)
||'.'||JournalName (TITLE 'Journals', CHARACTER(26))
FROM DBC.journals
ORDER BY 1,2;
You can also determine which tables in your system are currently being journaled using the
following query that has a somewhat different syntax:
SELECT TRIM(d.databasename)||'.'||TRIM(t.tvmname) (FORMAT
'x(45)',TITLE 'Table'),TRIM(dj.databasename)
||'.'||TRIM(tj.tvmname) (TITLE 'Journal')
FROM DBC.TVM
t
,DBC.TVM
tj
,DBC.dbase d
,DBC.dbase dj
WHERE t.journalid IS NOT NULL
AND
t.journalid <> '00'xb
AND
t.journalid = tj.tvmid
AND
d.databaseid = t.databaseid
AND
dj.databaseid = tj.databaseid
ORDER BY 1;
Also see “CREATE DATABASE” on page 198, “CREATE USER” on page 950, “MODIFY
DATABASE” on page 1071, and “MODIFY USER” on page 1086.
SQL Reference: Data Definition Statements
79
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
NO/DUAL Journaling
IF …
THEN the system maintains …
the JOURNAL keyword is specified without
NO or DUAL
a single copy of the image unless FALLBACK is in
effect or is also specified.
journaling is requested for a database that
uses fallback protection
DUAL images automatically.
BEFORE/AFTER Journaling
IF …
THEN …
the JOURNAL keyword is
specified without AFTER or
BEFORE
both types of images are maintained.
one type is specified
only the default for that type is overridden.
This option might appear twice in the same statement: once to
specify a BEFORE or AFTER image, and again to specify the
alternate type.
For example, if AFTER is specified, before image journaling remains
at the default setting.
both types are specified
the two specifications must not conflict.
LOCAL Journaling
See “Local Journaling” on page 202 and “CREATE TABLE” on page 648.
Maximum Number of Columns Per Table
A base table can contain a maximum of 2,048 columns. No more than 32 of those columns
can be defined with a LOB data type (see “Rules for Large Object Data Types” on page 70).
A maximum of 2,560 columns can be defined for a base table over its lifetime. Dropping
columns does not affect this rule.
If new columns need to be added that would exceed this number, you must create a new table.
You can use the SHOW TABLE statement and the INSERT … SELECT statement can be used
to create and load the spin-off table.
80
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Changing Column Attributes: NOT NULL/NULL
Changing column attributes in ANSI SQL is restricted to setting or dropping a default clause.
To change the attributes of an existing column, the ALTER TABLE statement must include the
ADD keyword.
The following table summarizes the allowable cases for converting or adding NULL to NOT
NULL, or NOT NULL to NULL columns:
WHEN you add this attribute to a column …
Composite changes are …
NULL
never permitted.
NOT NULL
permitted.
The following rules define how columns defined with NULL or NOT NULL attributes can be
altered:
This column type …
When defined as …
Can be altered to this column type …
Indexed
NULL
NULL only
NOT NULL
NOT NULL only
NULL
NOT NULL
Nonindexed
If and only if the column does not contain nulls.
NOT NULL
NULL
Modifying Column Data Types or Value Compression
You can compress nulls and as many as 25518 distinct values per column. You can compress an
unlimited number of columns per table. Nulls are always compressed by default.
IF you specify this type
of compression …
THEN …
single-valued
the default is null if no value is specified explicitly.
multivalued
• there is no default and all values must be specified explicitly; however, if
a column is nullable, then null compression is in effect even if it is not
specified explicitly.
• there is no essential ordering for specifying values to be compressed for
a given column.
• the same value cannot be specified more than once in the compression
value list for a given column.
18. This value is constrained by the maximum system row length because compressed values are added to the
table header row for each column.
SQL Reference: Data Definition Statements
81
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
You can add a new column with multivalued compression to an existing table, add
multivalued compression to an existing column, or you can drop compression from an
existing column by specifying the NO COMPRESS attribute.
If a column is constrained as NOT NULL, then none of the specifications in the compression
list can be the literal NULL.
Column compression is not supported for volatile tables or for the following types of
columns:
•
Identity
•
VARCHAR
•
LONG VARCHAR
•
VARGRAPHIC
•
VARBYTE
•
BLOB
•
CLOB
If the data type of any column in the new table is not compatible with the value of the
corresponding field in the existing table, individual INSERT statements must be used to load
each row.
If all the new data types are compatible with all the existing values (for example, only the
COMPRESS attribute is being changed), you can use an INSERT … SELECT statement to
copy all the rows in a single statement (see SQL Reference: Data Manipulation Statements).
Also see “Rules for Adding or Modifying Compression for a Column” on page 82.
See Database Design for more detailed information about value compression and its
applications for performance optimization and disk capacity savings.
Rules for Adding or Modifying Compression for a Column
The following rules apply to adding or modifying rows with compression:
•
For single-valued compression, the default for the compress value is NULL.
•
For multivalued compression, there is no default compress value.
All values in the value list must be specified explicitly.
•
Nulls in a nullable column are always compressed automatically, even if not explicitly
specified.
•
You can compress as few as 0 or as many as all but the primary index column set19 and any
variable length columns in a table.
•
The maximum number of distinct values that can be compressed per column is 255.
•
If an attempt to modify or add the definition for a new column results in the table row
header exceeding the maximum row length for the Teradata Database, then the responsible
ALTER TABLE request fails.
•
You can modify an existing column to have multivalued compression.
19. Nor can you compress partitioning column values when the primary index is partitioned.
82
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
In addition to the direct method of modifying an existing column to use multivalued
compression, there are two workarounds for cases where you want to convert an existing
column to support multivalued compression:
•
The procedure for the first workaround is as follows:
i
Use ALTER TABLE to add a new column with the desired multivalued
compression.
ii
Populate the new column by copying the data from the column it is designed to
replace.
iii Use ALTER TABLE to drop the old column.
iv Use ALTER TABLE to rename the new column to match the name of the dropped
column.
v
•
End of procedure.
The procedure for the second workaround is as follows:
i
Use CREATE TABLE with the desired multivalued compression defined where
needed.
ii
Populate the new table by copying the data from the old table using an INSERT …
SELECT.
iii Use DROP TABLE to drop the old table.
iv Use ALTER TABLE to rename the new table to match the name of the dropped
table.
v
•
•
End of procedure.
You can drop compression from an existing column or make values uncompressible for a
new column by specifying the NO COMPRESS option.
IF the specified column …
THEN you can use NO COMPRESS to …
already exists
drop the compression from the specified column.
does not already exist
make the column values not compressible for the specififed column.
The effect of adding the COMPRESS attribute to an existing column depends on the
specific definition of the COMPRESS clause, as is explained by the following cases. Note
that you cannot specify null compression if the specified column is defined with the NOT
NULL attribute.
•
In the following case, the system compresses nulls only for the specified column:
ALTER TABLE table_name
ADD column_name COMPRESS;
This is equivalent to the following request:
ALTER TABLE table_name
ADD column_name COMPRESS NULL;
SQL Reference: Data Definition Statements
83
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
In the following case, the system compresses nulls and the specified constant value for
the specified column:
ALTER TABLE table_name
ADD column_name COMPRESS <constant | NULL>;
If column_name already exists, and a compression value set is already defined for it,
then the newly specified compression value set replaces the existing set.
Note that the expression <constant | NULL> is not SQL, but is symbolic of a
specification of either a constant value (meaning that both that constant and nulls are
to be compressed for the specified column) or only the keyword NULL.
•
In the following case, the system compresses nulls and the specified list of constant
values for the specified column:
ALTER TABLE table_name
ADD column_name COMPRESS (<constant_list | NULL>);
If column_name already exists, and a compression value set is already defined for it,
then the newly specified compression value set replaces the existing set.
Note that the expression <constant_list | NULL> is not SQL, but is symbolic of a
specification of either a list of constant values (meaning that both that list of constants
and nulls are to be compressed for the specified column) or only the keyword NULL.
•
Specifying NO COMPRESS when adding a new column has the same effect as not
specifying COMPRESS for that column: the column is not compressible.
•
Specifying NO COMPRESS when modifying an existing column drops the COMPRESS
attribute from that column.
•
The ALTER TABLE MODIFY COMPRESS syntax supports the following:
•
Both loaded and empty tables of all types.
•
Global Temporary tables.
•
Secondary index columns with the following exception:
•
If the column is the PRIMARY KEY or FOREIGN KEY in a referential constraint,
then it cannot be compressed.
•
Base table columns on which a join index is defined.
•
Base table columns on which a hash index is defined.
•
Modification of multiple columns in a single ALTER TABLE request. For example, the
following ALTER TABLE request is valid:
ALTER
ADD
ADD
ADD
•
TABLE table_ex
column_1 COMPRESS (0,100, 200),
column_2 COMPRESS (‘Female’,’Male’),
column_3 COMPRESS (’Teradata’,’Teradata’);
Specification of changes to multiple options within the same ALTER TABLE request.
For example, the following ALTER TABLE request is valid:
ALTER TABLE table_ex
MODIFY column_1 COMPRESS (0,100, 200),
DROP column_2,
MODIFY column_3 COMPRESS (‘Teradata’,’Teradata’),
ADD column_4 INTEGER;
84
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
Changing a noncompressed column to have compression. For example,
ALTER TABLE table_ex
MODIFY column_4 COMPRESS (0, 1000, 10000);
•
Changing a compressed column to not being compressed. For example,
ALTER TABLE table_ex
ADD column_4 NO COMPRESS;
•
Adding compressed values to an existing compression value list. This can only be done
by replacing the existing compression value list for a column. For example, suppose
column_3 in table_ex already compresses the following set of values: WalMart,
JCPenney, Kmart.
The following ALTER TABLE request adds Harrahs to the list of compressed values for
column_3:
ALTER TABLE table_ex
MODIFY column_3
COMPRESS (‘WalMart’,’JCPenney’,’Kmart’,’Sears’,’Harrahs’);
•
Dropping compressed values from an existing compression value list. This can only be
done by replacing the existing compression value list for a column. For example,
suppose column_3 in table_ex already compresses the following set of values: WalMart,
JCPenney, Kmart, Sears, Harrahs.
The following ALTER TABLE statement drops Harrahs from the list of compressed
values for column_3:
ALTER TABLE table_ex
ADD column_3
COMPRESS (‘WalMart’,’JCPenney’,’Kmart’,’Sears’);
•
The ALTER TABLE MODIFY COMPRESS syntax does not support the following:
•
A compression list that exceeds the maximum size of 8,192 characters as defined by the
column DBC.TVField.CompressValueList.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression list that causes the table header to exceed its maximum size of 128
kilobytes.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression list that causes the Transient Journal to exceed its maximum size of
65,535 bytes.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression value or value list with values that are incompatible with the specified
data type for the column. An example of this would be attempting to add a character
string to a compression list for a column typed as INTEGER.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression value list that exceeds the maximum number of 255 unique values for a
column.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression value or value list that contains a value having a CHARACTER, BYTE,
or GRAPHIC data type with more than 255 characters.
When this occurs, the request aborts and the system returns an error to the requestor.
SQL Reference: Data Definition Statements
85
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
NULL compression when the column has a NOT NULL attribute.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression value or value list that contains a character that is not in the character
set for the current session.
When this occurs, the request aborts and the system returns an error to the requestor.
•
A compression value that duplicates a value that is already in the compression value
list. An example of this would be attempting to add the string ‘WalMart’ twice to a
compression value list for a CHARACTER column.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying the compression characteristics of the same column more than once in the
same ALTER TABLE statement.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying both the compression characteristics and the characteristics of a constraint
in the same ALTER TABLE statement.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying a primary index column, whether an NPPI or a PPI, to add compression.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Adding compression to a column that is a member of the partitioning column set for a
PPI table.
When this occurs, the request in Teradata session mode or the transaction in ANSI
session mode aborts and the system returns an error to the requestor.
•
Modifying any column that is part of a referential integrity constraint to add
compression.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying an identity column to add compression.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying a column that has any of the following data types to add compression:
•
VARCHAR
•
LONG VARCHAR
•
VARBYTE
•
VARGRAPHIC
•
BLOB
•
CLOB
•
A UDT, no matter what its underlying data type (or, if a structured UDT, data type
set) contains.
When this occurs, the request aborts and the system returns an error to the requestor.
•
Modifying a column of a Volatile table to add compression.
When this occurs, the request aborts and the system returns an error to the requestor.
86
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
The expanded compress values for a column are stored in the data dictionary.
If the text exceeds the 8,192 character maximum size for DBC.TVFields.CompressValueList,
then the responsible ALTER TABLE request fails.
•
The list of compressed values for a nullable column can be null or one or more distinct
constant values.
•
The list of compressed values for a non-nullable column cannot include nulls.
•
You cannot specify the same distinct value more than once in a compressed value list.
Adding and Dropping CHECK Constraints
The following rules apply to using CHECK constraints with the ALTER TABLE statement:
•
The following table explains rules for ADD and MODIFY:
THIS form …
IS allowed only if column_name does …
ADD column_name CHECK
(boolean_condition)
not already have a constraint.
MODIFY
have a constraint.
Note that only one CHECK modification can be made per ALTER TABLE statement and
that CHECK and non-CHECK alterations cannot be combined within a single ALTER
TABLE statement.
•
The following form drops all unnamed column level CHECK constraints on
column_name:
ALTER TABLE table_name DROP column_name CHECK
•
The following form drops all unnamed table level CHECK constraints on the table name:
ALTER TABLE table_name DROP CHECK
•
Either of the following is legitimate syntax for dropping a named CHECK constraint:
DROP CONSTRAINT name CHECK
DROP CONSTRAINT name
•
The following form is valid only if a constraint with name already exists in the table:
MODIFY CONSTRAINT name CHECK (search condition)
This also applies to the named constraints defined as part of the column definition
because those constraints are handled as named table-level constraints.
•
To ensure maximum system performance, there is a limit of 100 table-level constraints
that can be defined for any table.
A combination of table-level, column-level, and WITH CHECK on view constraints can
create a constraint expression that is too large to be parsed for INSERT and UPDATE
statements.
•
CHECK constraints are not supported for global temporary tables.
SQL Reference: Data Definition Statements
87
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
•
Details of adding and dropping constraints with ALTER TABLE are explained in the
following table:
IF you perform this statement …
THEN you add/drop the following number of unnamed
table level CHECK constraints …
ALTER TABLE … DROP CHECK
all.
anything else
one per ALTER TABLE statement, regardless of
constraint type.
A CHECK constraint can neither be defined for nor reference a LOB column.
Adding or Dropping PRIMARY KEY and UNIQUE Constraints
ALTER TABLE … ADD UNIQUE/PRIMARY KEY requires the following privileges:
•
DROP TABLE on the table or its database
•
INDEX on the table
The following rules apply to adding and dropping PRIMARY KEY and UNIQUE constraints:
•
You can add a PRIMARY KEY constraint if and only if no primary key is already defined
for the table.
There are no exceptions to this rule.
The added primary key always maps to a unique secondary index (USI).
•
You cannot add a PRIMARY KEY or UNIQUE constraint to the QITS column of a queue
table.
•
You can drop a PRIMARY KEY constraint if and only if it is mapped to a unique secondary
index (USI). In other words, you cannot drop a PRIMARY KEY constraint if it is mapped
to the primary index of a table. See “Primary Index Default Definitions” on page 725.
•
For a table with a NUPI, you can only add a PRIMARY KEY or UNIQUE constraint on the
same set of columns as the primary index column list if a USI is not explicitly defined on
the same column set as the primary index.20
•
Use the DROP INDEX statement to drop unnamed UNIQUE constraints.
•
A PRIMARY KEY or UNIQUE constraint cannot be defined for a LOB column.
Adding or Dropping Referential Integrity Constraints
Referential integrity is a rule that prevents rows in a child table from being orphaned from the
rows they refer to in a parent table. When a referential integrity relationship is established
between a primary or alternate key for a parent table and a foreign key in a child table, the
system does not permit you to update or delete the referenced parent table key without first
updating or deleting rows containing the foreign key in the child table.
20. Any such PRIMARY KEY or UNIQUE constraint implicitly defines a USI on the same set of columns as
those defining the primary index column list.
88
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
The following rules apply to adding and dropping referential integrity constraints:
•
The user issuing the ALTER TABLE statement containing a REFERENCES option must
have the REFERENCE privilege on the referenced table or on all specified columns of the
referenced table.
•
You can only add or drop one foreign key reference and it cannot contain any options
other than to add or drop the foreign key.
•
The columns in the referenced parent table must be defined uniquely, either as the
primary key for the table, with a UNIQUE column attribute, or as a USI.
•
The foreign key columns in the referencing child table must be identical to the key in the
referenced table.
•
You cannot define a referential constraint on a LOB column in a child table, nor can you
define a referential constraint to a LOB column in the parent table.
•
You cannot add either of the following constraints to a queue table definition:
•
•
FOREIGN KEY … REFERENCES
•
REFERENCES
You cannot add either of the following constraints to a non-queue table definition if the
target table for that reference is a queue table:
•
FOREIGN KEY … REFERENCES
•
REFERENCES
•
You cannot compress either key value in a referential relationship. The system does not
compare column-level constraints for the referentially related columns.
•
Referential integrity is not supported for global temporary, trace, queue, or volatile tables.
See Database Design for more information about referential integrity.
The following process describes the error handling processes involved in adding any new
referential constraint, whether it checks referential integrity or not, to a table:
1
The system generates an error table21 when the new constraint is added to the table.
•
Its name is the name of the target table suffixed with the appropriate reference index
number.
A different reference index number is assigned to each foreign key constraint defined
for the table. You can determine reference index numbers using the
RI_Distinct_Children or RI_Distinct_Parents system views (see Data Dictionary).
•
Its columns and primary index22 are the same as those of the target table.
21. This is a different error table than the one you create to log minibatch bulk loading errors (see “CREATE
ERROR TABLE” on page 205).
22. If the primary index is partitioned, then the partitioning columns in the parent and child tables must also
be the same.
SQL Reference: Data Definition Statements
89
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
2
The error table is created under the same user or database as the table being altered.
IF …
THEN the system …
a table with the same name as that generated
for the error table already exists
returns an error.
rows in the referencing table contain values in
the foreign key columns that cannot be found
in any row of the referenced table
does not return an error.
Instead, a row is inserted into the error table
for each such row found in the target table.
Use these rows to determine the corrections
that must be made.
You are responsible for correcting values in the referenced or referencing tables so that full
referential integrity exists between the two tables.
You are also responsible for maintaining the error table, including deleting it after any
errors have been corrected.
3
End of process.
Adding or Dropping Batch Referential Integrity Constraints
Batch referential integrity is similar to standard referential integrity because it enforces the
referential integrity constraints it defines. This constraint differs from standard referential
integrity with respect to when it is validated and how non-valid rows are treated. The rules for
adding or dropping batch referential integrity constraints are identical to those documented
by “Adding or Dropping Referential Integrity Constraints” on page 88. See “Example 38: Add
or Drop a Batch Referential Constraint” on page 129.
Adding or Dropping Referential Constraints
Referential Constraints provide the Optimizer with an efficient method for producing better
query plans that take advantage of defined, but unenforced, referential relationships. Other
than not enforcing referential integrity, the rules for soft referential integrity constraints are
identical to those documented by “Adding or Dropping Referential Integrity Constraints” on
page 88. See “Referential Constraint” on page 708 and “Example 39: Adding a Table-Level
Referential Constraint” on page 130 for additional information.
Maintaining Foreign Key Integrity
The system verifies that the structure of columns defined as foreign keys, or referenced by
foreign keys, is not changed in any manner that violates the rules for the definition of a foreign
key constraint.
An ALTER TABLE (or DROP INDEX) statement attempting to change the structure of such a
column aborts and causes the system to return an error to the requestor.
The system verifies that a table referenced by another is not dropped. Before dropping the
table, you must perform an ALTER TABLE statement to drop the foreign key reference.
90
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Referential Integrity When a Table Is Inconsistent
While a table is marked as inconsistent, no updates, inserts, or deletes are permitted. The table
is fully usable only when the inconsistencies are resolved. This restriction is true for both hard
and soft (Referential Constraint) referential integrity constraints.
It is possible that the user either intends to or must revert to a definition of a table which
results in an inconsistent reference on that table. The Archive and Restore operations are the
most common cause of such inconsistencies.
After the child table is archived, the parent table can be dropped.
When the child table is restored, the parent table no longer exists. The normal ALTER TABLE
DROP FOREIGN KEY statement does not work, because the parent table references cannot be
resolved.
You can use the DROP INCONSISTENT REFERENCES option to remove these inconsistent
references from a table.
The syntax is:
ALTER TABLE database_name.table_name DROP INCONSISTENT REFERENCES
You must have DROP privileges on the target table of the statement to perform this option,
which removes all inconsistent internal indexes used to establish references.
Data Type and Attribute Definitions
The data type defined for a column can be changed only if the new type does not require a
change to the existing data. The rules for changing the data type of a column are listed in
“Rules for Changing the Column Data Type” on page 92. Also see “Procedure to Change
Column Data Types” on page 96.
For an existing column, the following rules are true for data types and attributes with the
exception of LOB data types.
You can specify either of the following:
•
FORMAT, TITLE, DEFAULT, or WITH DEFAULT phrases.
•
Changes in data type attributes or in data types in cases where the change does not require
rewriting existing rows.
SQL Reference: Data Definition Statements
91
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
The following table provides examples of valid and non-valid type and attribute definition
changes:
Changing this form …
TO this form …
IS …
CASESPECIFIC
NOT CASESPECIFIC
valid
NOT CASESPECIFIC
CASESPECIFIC
valid
CASESPECIFIC
UPPERCASE
not valid
VARCHAR(6)
VARCHAR(12)
valid
VARCHAR(12)
VARCHAR(6)
not valid
For LOB data types, you can only alter the following column attributes:
•
NULL
•
NOT NULL
•
TITLE
•
FORMAT
No other data type attributes are permitted for BLOB or CLOB data.
Changing a Data Type Attribute
The display attributes FORMAT and TITLE can be altered at any time and a new DEFAULT
declared. The following rule applies to this class of table modifications:
•
You can declare either the CASESPECIFIC or the NOT CASESPECIFIC attribute for
character columns.
Rules for Changing the Column Data Type
The following table illustrates the rules for changing a data type from the existing type to a
new type.
You cannot change the character set attribute of an existing column. For example, once a
column has been defined as LATIN, you cannot change it to UNICODE.
Old Data Type
92
New Data Type
Restrictions on Changes
All
All
Cannot change for a column used in a primary or
secondary index.
CHAR(n), UC
CHAR(n)
CHAR(n)
CHAR(n), CS
Lengths must remain identical. Can change only
case specific setting.
CHARACTER
CHARACTER(n)
Not allowed if n > 1.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Old Data Type
CHARACTER
New Data Type
DATE
Restrictions on Changes
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of DATE
string literal.
If conversion is not possible, an error is returned.
CHARACTER
TIME
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of TIME
string literal.
If conversion is not possible, an error is returned.
CHARACTER
TIMESTAMP
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of
TIMESTAMP string literal.
If conversion is not possible, an error is returned.
CHARACTER
INTERVAL
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of
INTERVAL string literal.
If conversion is not possible, an error is returned.
VARCHAR(m), UC
VARCHAR(n)
Cannot decrease maximum length. Cannot change
from no UC to UC.
GRAPHIC
GRAPHIC(n)
Not allowed if n > 1.
VARGRAPHIC(m)
VARGRAPHIC(n)
Cannot decrease maxlength.
BYTE
BYTE(n)
Not allowed if n > 1.
VARBYTE(m)
VARBYTE(n)
Cannot decrease maximum length.
Exact NUMERIC
INTERVAL
INTERVAL must have a single field only and
numeric value must be in the range permitted for an
INTERVAL value; otherwise, an error is returned.
DATE
INTEGER
No restrictions.
INTEGER
DATE
Cannot make this change because INTEGER
column could include non-valid DATE values.
DECIMAL(n,0)
INTEGER
Can change only if n is in range 5 - 9, inclusive.
DECIMAL(n,0)
BIGINT
Can change only if n is in range 10 - 18, inclusive.
DECIMAL(n,0)
SMALLINT
Can change only if n is 3 or 4.
DECIMAL(n,0)
BYTEINT
Can change only if n = 1 or 2.
SQL Reference: Data Definition Statements
93
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Old Data Type
CHARACTER
New Data Type
DATE
Restrictions on Changes
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of DATE
string literal.
If conversion is not possible, an error is returned.
CHARACTER
TIME
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of TIME
string literal.
If conversion is not possible, an error is returned.
CHARACTER
TIMESTAMP
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of
TIMESTAMP string literal.
If conversion is not possible, an error is returned.
CHARACTER
INTERVAL
Value trimmed of leading and trailing blanks and
handled like a quoted string in declaration of
INTERVAL string literal.
If conversion is not possible, an error is returned.
94
VARCHAR(m), UC
VARCHAR(n)
Cannot decrease maximum length. Cannot change
from no UC to UC.
GRAPHIC
GRAPHIC(n)
Not allowed if n > 1.
VARGRAPHIC(m)
VARGRAPHIC(n)
Cannot decrease maxlength.
BYTE
BYTE(n)
Not allowed if n > 1.
VARBYTE(m)
VARBYTE(n)
Cannot decrease maximum length.
Exact NUMERIC
INTERVAL
INTERVAL must have a single field only and
numeric value must be in the range permitted for an
INTERVAL value; otherwise, an error is returned.
DATE
INTEGER
No restrictions.
INTEGER
DATE
Cannot make this change because INTEGER
column could include non-valid DATE values.
DECIMAL(n,0)
INTEGER
Can change only if n is in range 5 - 9, inclusive.
DECIMAL(n,0)
BIGINT
Can change only if n is in range 10 - 18, inclusive.
DECIMAL(n,0)
SMALLINT
Can change only if n is 3 or 4.
DECIMAL(n,0)
BYTEINT
Can change only if n = 1 or 2.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Old Data Type
DECIMAL(n,f)
New Data Type
DECIMAL(m,f)
Restrictions on Changes
Can change only as follows:
•
•
•
•
•
m >= n, no change in f
n = 1 or 2, m < 3
n = 3 or 4, m < 5
n = 5 to 9, m < 10
n = 10 to 15, m <= 18
DATE
DATE
No restrictions.
DATE
CHARACTER
No restrictions.
Result might not be in ANSI date format.
DATE
TIME
No restrictions.
DATE
TIMESTAMP
Year, month, and day are taken from source date
value. Hour, minute, and seconds are set to 0.
If target specifies TIMESTAMP WITH TIME
ZONE, the time zone fields are taken from the
explicit or implicit values for the source.
TIME
TIME
If target is TIME WITH TIME ZONE, then time
zone displacement value is added; otherwise, value
is adjusted to the current time zone displacement
for the session.
TIME
TIMESTAMP
INTERVAL
CHARACTER(n)
n must be >= length of the value.
If n > value, then trailing blanks are added.
If n < value, an error is reported.
TIME
TIMESTAMP
INTERVAL
VARCHAR
Same as conversion to CHARACTER except no
trailing blanks are added when n > value.
TIME
TIMESTAMP
No restriction.
Year, month, and day are set to the values for
CURRENT_DATE. If target also specifies TIME
ZONE, the time zone values are taken from the
explicit or implicit values for the source.
TIME WITH TIME
ZONE
TIME
No restriction, but TIME ZONE value is removed.
TIMESTAMP
TIMESTAMP WITH
TIME ZONE
DATE
Result is year, month, and day from TIMESTAMP
value after adjustment for TIME ZONE, if present.
TIMESTAMP
TIMESTAMP
No restriction.
If source and target differ on value for WITH TIME
ZONE, conversion is required, which can change
the values in the result.
SQL Reference: Data Definition Statements
95
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Old Data Type
New Data Type
Restrictions on Changes
TIMESTAMP
TIME
Result is taken from hour, minute, and second
fields. If target is TIME WITH TIME ZONE, then
time zone displacement is added; otherwise value is
adjusted to the current time zone displacement of
the session.
INTERVAL (n)
INTERVAL (m)
Can change only if m>=n and is Year-Month or
Day-Time compatible.
You cannot mix Year-Month intervals with
Day-Time intervals.
Procedure to Change Column Data Types
To make a change to a column data type that affects existing column data, use the following
procedure:
1
Create a new table with a different name that contains the changed data type attributes.
2
Populate the new table using an INSERT … SELECT statement.
3
Catalog the access privileges of the old table before step 4. Use the following syntax:
SELECT username, accessright, grantauthority, columnname,
allnessflag
FROM dbc.allrights
WHERE tablename = ‘table_name’
AND
databasename = ‘database_name’;
4
Drop the old table.
5
Rename the new table with the name of the old table.
As an example, use the following sequence of statements to expand the data type attribute
for the name column from 12 to 14 characters:
CREATE TABLE temp, FALLBACK (
EmpNo INTEGER NOT NULL FORMAT ZZZZ9,
Name CHARACTER(14) NOT NULL,
…
HCap BYTEINT FORMAT ’Z9’)
UNIQUE PRIMARY INDEX (index_name) ;
6
Once the table is created, populate it, drop the old employee table, and rename the
temporary table.
The following example shows how this is done:
INSERT INTO temp
SELECT *
FROM employee;
DROP TABLE employee;
RENAME TABLE temp TO employee;
A different name, temp, is used in recreating the employee table because the employee table
already exists. If you enter a CREATE TABLE statement for an existing table, you receive an
error.
96
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
To facilitate recreating a table according to Step 1, you can display the CREATE TABLE
statement for the table by running the SHOW TABLE statement.
For example, the following statement displays a reconstruction of the CREATE TABLE
statement for table dept_em:
SHOW TABLE dept_em;
If you are using BTEQ, when the CREATE TABLE statement is displayed, you can change
the statement (that is, change the table name and index) using BTEQ edit commands and
submit the new table definition using the BTEQ SUBMIT command.
7
Grant the same access privileges to the employee table again, as they were lost when the
table was dropped. Use the same access privileges cataloged in step 3.
8
End of procedure.
Increasing the length of VARCHAR or VARBYTE does not change the current format. Instead,
you should consider including a new FORMAT phrase in the statement.
ALTER TABLE provides many extensions not offered by ANSI SQL. For example, changing
column attributes in ANSI SQL is restricted to setting or dropping a default clause, which is
not the case for SQL in the Teradata Database.
Redefining the Primary Index
There are three ways to redefine the primary index for a table:
•
Use the primary index modification syntax for ALTER TABLE to modify the index (see
“Primary Index Modification Syntax” on page 56 and “General Rules for the MODIFY
PRIMARY INDEX Option” on page 102).
•
Create a new table with the primary index defined properly and then use an
INSERT ... SELECT to copy the data from the old table to the new table (see “Redefining a
Primary Index Without Using ALTER TABLE” on page 99).
•
Use the CREATE TABLE AS syntax (see “CREATE TABLE (AS Clause)” on page 750) to:
a
Create a new table with the primary index defined properly.
b
Copy the data from the old table into the new table.
c
End of procedure.
SQL Reference: Data Definition Statements
97
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
You can use ALTER TABLE to perform the following changes for primary indexes:
To perform this operation …
Specify …
Change a NUPI to a UPI
MODIFY UNIQUE PRIMARY INDEX in the Primary Index
Change Options clause (see “General Rules for the MODIFY
PRIMARY INDEX Option” on page 102).
Change a UPI to a NUPI
MODIFY NOT UNIQUE PRIMARY INDEX in the Primary
Index Change Options clause (see “General Rules for the
MODIFY PRIMARY INDEX Option” on page 102).
Change a PPI to an NPPI
NOT PARTITIONED in the Primary Index Change Options
clause (see “General Rules for the MODIFY PRIMARY INDEX
Option” on page 102 and “Rules For Altering the Partitioning
Expression For a Primary Index” on page 108).
To do this, the table must be empty.
Change an NPPI to a PPI
a PARTITION BY clause within the Primary Index Change
Options clause (see “General Rules for the MODIFY
PRIMARY INDEX Option” on page 102 and “Rules For
Altering the Partitioning Expression For a Primary Index” on
page 108).
To do this, the table must be empty.
Add or drop PPI partitioning
expression ranges
an ADD RANGE or DROP RANGE clause within the Primary
Index Change Options clause (see “General Rules for the
MODIFY PRIMARY INDEX Option” on page 102 and “Rules
and Guidelines for Adding and Dropping Ranges in a
Partitioning Expression” on page 111).
Add or drop primary index
columns
MODIFY PRIMARY INDEX in the Primary Index Change
Options clause (see “General Rules for the MODIFY
PRIMARY INDEX Option” on page 102).
To do this, the table must be empty.
Validate a PPI by regenerating
its table headers and correcting
any errors in row partitioning
a REVALIDATE PRIMARY INDEX clause within the Primary
Index Change Options clause (see “General Rules for the
REVALIDATE PRIMARY INDEX Option” on page 117).
A primary index cannot contain any LOB columns.
Note that you cannot change the primary index for an error table (see “CREATE ERROR
TABLE” on page 205).
98
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Redefining a Primary Index Without Using ALTER TABLE
To redefine the primary index for a table without using an ALTER TABLE statement, perform
a procedure similar to that described in “Procedure to Change Column Data Types” on
page 96. There are several methods that you can use to achieve this, neither of which is better
than the other:
•
•
First method:
a
Copy the table into a newly defined table defined with a different primary index and
populate it using the CREATE TABLE AS syntax (see “CREATE TABLE (AS Clause)”
on page 750).
b
Catalog the access privileges on the old table. See step 3 in “Procedure to Change
Column Data Types” on page 96.
c
Drop the original table (see “DROP MACRO/ DROP PROCEDURE/ DROP TABLE/
DROP TRIGGER/ DROP VIEW” on page 1027).
d
Rename the new table (see “RENAME MACRO/ RENAME PROCEDURE/ RENAME
TABLE/ RENAME TRIGGER/ RENAME VIEW” on page 1109).
e
Grant access privileges on the new table (see “GRANT (SQL Form)” on page 1199).
f
End of procedure.
Second method:
a
Using a different name, create a new table that specifies the new index.
b
Populate the new table using an INSERT … SELECT statement (see SQL Reference:
Data Manipulation Statements).
c
Catalog the access privileges on the old table. See step 3 in “Procedure to Change
Column Data Types” on page 96.
d
Drop the original table (see “DROP MACRO/ DROP PROCEDURE/ DROP TABLE/
DROP TRIGGER/ DROP VIEW” on page 1027).
e
Rename the new table with that of the old table (see “RENAME MACRO/ RENAME
PROCEDURE/ RENAME TABLE/ RENAME TRIGGER/ RENAME VIEW” on
page 1109).
f
Grant access privileges on the new table (see “GRANT (SQL Form)” on page 1199).
g
End of procedure.
SQL Reference: Data Definition Statements
99
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Performance Implications of Altering a Primary Index Using ALTER TABLE
You should consider the following information about the immediate performance impact of
altering the primary index for a table to best schedule the operation in a way that has the least
impact on your production workload:
•
Altering an empty table is fairly quick.
•
Altering the table to have a unique or nonunique primary index is fairly quick.
•
Altering the table to change the primary index name is fairly quick.
•
The following cumulative performance issues are all concerned with dropping or adding
new ranges or partitions to a PPI:
•
When dropping or adding new ranges or partitions for a populated table, the
operation can be fairly quick because rows that remain in the retained ranges and
partitions need not be processed or repartitioned.
•
There is an additional small overhead if dropped ranges and partitions are populated,
and still further overhead if any referential integrity constraints are defined on the
table.
•
There is additional overhead if new ranges are added and there are populated NO
RANGE [OR UNKNOWN) or UNKNOWN partitions or rows in dropped ranges that
need to be moved to the added ranges because rows must be processed to determine if
any of them need to be assigned to one of the new ranges and, if so, to move them to
the correct range.
•
You must update any secondary, join, or hash indexes on the table.
Updating secondary, join, and hash indexes can be lengthy operations and depend on
several factors, including the size of the table and indexes and the number of rows
deleted or moved.
•
There is additional overhead if the deleted rows are inserted into a save table. The
degree of this overhead depends on the number of rows that must be inserted into the
save table and the other standard performance issues associated with inserting rows
into a table.
•
If a table is defined with a NO RANGE partition, specifying a WITH DELETE or
WITH INSERT INTO clause in an ALTER TABLE statement used to change its
definition has no effect.
In this case, rows from deleted partitions and rows whose partition number evaluates
to something other than 1 - 65 535, inclusive, are retained in the NO RANGE partition
rather than being moved to the target table specified in the WITH DELETE or WITH
INSERT INTO clause.
See “Purpose and Behavior of the NO RANGE and UNKNOWN Partitions” on
page 736 and “Rules For Altering the Partitioning Expression For a Primary Index” on
page 108 for additional information.
100
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
General Rules for the Primary Index Options Clause
The following rules apply to both the MODIFY PRIMARY INDEX option and the
REVALIDATE PRIMARY INDEX option of the Primary Index Options clause:
•
You cannot alter the primary index for any of the following database objects using the
ALTER TABLE statement:
• Global temporary tables • Compressed join indexes
• Volatile tables
• Hash indexes
•
You cannot modify the primary index of a join index.
•
You must disable some triggers before you can perform an ALTER TABLE statement that
modifies or revalidates the primary index for a table.
IF you specify this clause in an ALTER
TABLE statement that modifies or
revaluates the primary index …
THEN you must disable these triggers before you
perform the statement …
WITH DELETE
all delete triggers on table_name.
After the ALTER TABLE statement completes, you can
reenable the disabled triggers.
WITH INSERT
SQL Reference: Data Definition Statements
• all delete triggers on table_name.
• all insert triggers on save_table.
After the ALTER TABLE statement completes, you can
reenable the disabled triggers.
101
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
General Rules for the MODIFY PRIMARY INDEX Option
The following general rules and observations apply to the Modify Primary Index option of the
Primary Index Options Clause (see “Rules For Altering the Partitioning Expression For a
Primary Index” on page 108 for the subset of rules that apply to partitioning expressions):
•
You cannot modify both primary index and non-primary index table definitions within a
single ALTER TABLE statement because the operations are mutually exclusive.
•
You cannot modify both primary index definitions and revalidate a primary index within a
single ALTER TABLE statement because the operations are mutually exclusive.
•
You cannot specify the system-derived column PARTITION or PARTITION#Ln in any of
its forms in the definition of a new partitioning expression.23
•
Any change to how a primary index is partitioned affects the values for the system-derived
PARTITION and PARTITION#Ln columns for most, if not all, rows in a table.
•
Any change to the structure of a table increments its version number.
This means that you cannot perform any of the following actions over a DDL statement
that alters table structure:
•
Cluster restore
•
Single AMP restore
•
Rollforward or rollback of a permanent journal
If the ARC utility encounters such a structural table change during a rollforward or
rollback operation, then that operation is stopped and an error message is returned in the
output listing.
•
At least one specified option must change the definition of the primary index or an error is
returned.
Specifying different partitioning expressions for an existing PPI table is considered to be a
valid change even if the results of the new expressions are identical to those produced by
the former partitioning expressions.
•
The following rules apply to changing the name of a primary index:
•
The index_name cannot be the same as the name of any secondary index or constraint
defined for the table.
•
If you specify index_name, then that is the name of the primary index.
•
If you specify NOT NAMED, then the primary index has no name.
•
If you specify neither an index_name nor a NOT NAMED phrase, then no change is
made to the current name.
•
If you do not specify a column set for the primary index, then the existing column set for
the primary index is retained.
•
If there is a foreign key reference to or foreign key constraint on either the current or
resulting set of primary index columns, then you can only change the name of the index.
Otherwise, an error is returned.
23. This includes the system-derived columns PARTITION#Ln, where n ranges from 1 through 15, inclusive.
102
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
If you specify a column set for the primary index of a populated table, then that column set
must be identical to the existing column set for the primary index.
Conversely, you can specify a column set for the primary index that differs from the
current primary index column set only if the table is empty.
Otherwise, the system returns an error.
•
If you specify a column set for the primary index of a populated table that differs from a
current primary index that is defined implicitly by a PRIMARY KEY or UNIQUE
constraint, then the system drops that PRIMARY KEY or UNIQUE constraint.
•
If the current primary index for a table is defined implicitly by a PRIMARY KEY or
UNIQUE constraint and you use ALTER TABLE to specify a PARTITION BY phrase, then
the system drops that PRIMARY KEY or UNIQUE constraint.
•
You cannot modify the primary index of a queue table to make it a PPI. Queue tables
cannot have partitioned primary indexes.
•
If you specify a NOT PARTITIONED phrase and the existing table has a PPI, then its
primary index is modified to be an NPPI if the table is empty.
If the table is not empty, then the system reports an error.
•
If you specify a NOT PARTITIONED phrase and the existing table has an NPPI, then the
primary index is not changed with respect to its partitioning.
•
If you specify neither a PARTITIONED BY nor a NOT PARTITIONED phrase, then the
primary index is not changed with respect to its partitioning.
•
If you specify a UNIQUE phrase, then the new primary index for the table is a UPI.
Note that a PPI can be unique only if all its partitioning expression columns are also
included in the column set defining the primary index itself.
You cannot specify UNIQUE unless at least one of the following conditions is true for the
current primary index for the table:
•
The primary index is already a UPI.
•
The primary index is defined implicitly by a PRIMARY KEY or UNIQUE constraint.
•
An existing USI is defined on the same column set as the new UPI.
The existing USI can be specified either explicitly or implicitly by a PRIMARY KEY or
UNIQUE constraint.
•
The table is empty.
Otherwise, the system returns an error.
•
If a resulting primary index is unique and if there is also an existing USI on the same
column set, whether explicitly or implicitly defined, then that USI and any associated
PRIMARY KEY or UNIQUE constraint is dropped because it is redundant.
•
If a resulting primary index is a NUPI and the current primary index was implicitly
defined by a PRIMARY KEY or UNIQUE constraint, then that constraint is dropped.
•
If you specify a NOT UNIQUE phrase, then the new primary index for the table is a NUPI.
SQL Reference: Data Definition Statements
103
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
If you specify neither UNIQUE nor NOT UNIQUE, then the uniqueness of the primary
index for the table is not changed.
•
You cannot modify a primary index definition to include a LOB column.
LOB columns cannot be members of any index or partitioning column set.
Rules and Usage for the MODIFY PRIMARY INDEX Option For Multilevel
Partitioned Primary Indexes
The usage rules for MODIFY … PRIMARY INDEX apply to the multilevel case with the
following exception:
•
If you specify PARTITION BY, the system accepts the request and alters the table to have a
PPI with the specified new partitioning expressions as long as one of the following is true:
•
The table is empty.
•
The new partitioning expressions are defined by DROP RANGE[L#n] and ADD
RANGE[L#n] options that do not drop ranges other than from the beginning or end of
the ranges, with at least one remaining range, and then does not add ranges between
the resulting beginning and end of the ranges.
In addition, if the table has a multilevel PPI and the modification of a partitioning
expression includes dropping the NO RANGE [OR UNKNOWN] or UNKNOWN
partitions, that partitioning expression must not have previously been modified.24
For other than the first level, the total number of partitions for a level must not change.
In other words, the number of partitions dropped must be the same as the number of
partitions added in the ALTER TABLE request for that level.
Note that any excess partitions are reserved for level 1. That is, the maximum number
of partitions for level 1 is the following:
Maximum number of partitions for level 1 =
65,535
---------------n
∏d i
i=2
where:
Equation element …
Specifies …
the floor, or lower truncated value, of the expression.
di
the number of partitions at level i.
You can alter level 1 to have between 1 (if an SLPPI) or 2 (if an MLPPI) and this
maximum number of partitions.
Otherwise, the system aborts the request and returns an error message to the requestor.
24. Or has only been modified such that dropping the RANGE[OR UNKNOWN] or UNKNOWN partitions
would not cause an internal partition number to be skipped in the sequence of internal partition numbers
for the ranges.
104
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
The rows of an SLPPI table have one of the following two implied index CHECK
constraints:
CHECK
A
(
BETWEEN
CAST ( partitioning_expression )
(
1
AND
AS INTEGER
)
)
A
max
1094A080
CHECK
(
partitioning_expression
BETWEEN
1
AND
max
1094A081
where:
Syntax element …
Specifies the …
partitioning_expression
partition number returned by the SLPPI partitioning expression.
max
maximum number of partitions defined by partitioning_expression.
IF the partitioning expression is
defined with …
THEN the value of max is …
other than just a RANGE_N or
CASE_N function
65,535 or less.
only a RANGE_N or CASE_N
function
the number of partitions
defined by the function.
If an existing row violates the new partitioning expressions and you have not specified a
WITH DELETE or WITH INSERT clause, then you cannot apply the new partitioning.
Note that the rows of an MLPPI table have a different implied index CHECK constraint
(see “Rules and Usage for the MODIFY PRIMARY INDEX Option For Multilevel
Partitioned Primary Indexes” on page 104).
The implied constraint containing the CAST expression has a partitioning expression that
evaluates to a non-INTEGER data type, while the partitioning expression in the other
implied constraint evaluates to an INTEGER number without conversion.
•
The rows of a MLPPI table have the following implied index CHECK constraints:
CHECK
A
AND
( / * nn * /
partitioning_expression_1
IS NOT NULL
A
partitioning_expression_2
IS NOT NULL
B
B
)
13
AND
partitioning_expression_n
IS NOT NULL
1094A079
SQL Reference: Data Definition Statements
105
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
where:
Syntax element …
Specifies the …
nn
number of partitioning expressions or levels.
partitioning_expression_2
partition number returned by the second MLPPI partitioning
expression.
partitioning_expression_n
partition number returned by the nth MLPPI partitioning
expression.
Note the following:
• if the MLPPI has 3 levels, then there must be 3 NOT NULL
partitioning expressions in the implied constraint
• if the MLPPI has 10 levels, then there must be 10 NOT NULL
partitioning expressions in the implied constraint
and so on.
For this example, assume the following table has been created in database current_orders:
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
PRIMARY INDEX (o_orderkey)
PARTITION BY (
RANGE_N(o_custkey
BETWEEN 0
AND 49999
EACH 100),
RANGE_N(o_orderdate BETWEEN DATE '2000-01-01'
AND
DATE '2006-12-31'
EACH INTERVAL '1' MONTH))
UNIQUE INDEX (o_orderkey);
The constraint text for this multilevel partitioned primary index is as follows:
CHECK (/*02*/ RANGE_N(o_custkey BETWEEN 0 AND 49999 EACH 100) IS
NOT NULL AND RANGE_N(o_orderdate BETWEEN DATE '2000-01-01' AND
DATE '2006-12-31' EACH INTERVAL '1' MONTH) IS NOT NULL )
You could use the following query to retrieve index constraint information for each of the
multilevel partitioned objects:
SELECT *
FROM DBC.TableConstraints
WHERE ConstraintType = 'Q'
AND
SUBSTRING(TableCheck FROM 1 FOR 13) >= 'CHECK (/*02*/'
AND
SUBSTRING(TableCheck FROM 1 FOR 13) <= 'CHECK (/*15*/';
106
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
If an existing row violates a new partitioning expression, and you have not specified a
WITH DELETE or WITH INSERT clause, then you cannot apply it.
Rows that violate the implied index CHECK constraint, including those whose
partitioning expression evaluates to null, are not allowed in the table.
•
For an NPPI table, the condition PARTITION <> 0 should always evaluate to FALSE for
all rows in the table; however, the Optimizer does not make this assumption in order to
enable the condition to be validated.
For example, you can use the following query to select rows where PARTITION <> 0:
SELECT *
FROM nppi_table_name
WHERE PARTITION <> 0;
If things are working correctly, the retrieve step could skip reading the rows of the table;
however, the retrieve step does read all the rows in order to validate the condition. The
query returns a row only if its ROWID value is incorrect or if the process of extracting the
partition number from the ROWID is not working correctly.
•
The condition PARTITION#Ln <> 0, where n is greater than the number of levels defined
for the table (or the table is an NPPI table) should always evaluate to FALSE for all rows in
the table; however, the Optimizer does not make this assumption in order to enable the
condition to be validated.
For example, you can use the following query to select rows where PARTITION#Ln <> 0:
SELECT *
FROM ppi_table_name
WHERE PARTITION#Ln <> 0;
If things are working correctly, all partitions for the table could be eliminated for the
retrieve step; however, the system does not perform partition elimination for this
condition.
The query returns a row only for the following scenarios:
•
•
The ROWID value is incorrect
•
The process of extracting the partition number from the ROWID is not working
correctly
A system-derived column PARTITION#Ln is equivalent to a value expression where the
expression is the same as the partitioning expression at the specified level as defined for the
primary index of the table with column references appropriately qualified as needed.
The value expression evaluates to 0 for the following cases:
•
There is no partitioning expression for the level
•
The primary index is not partitioned
This equivalence is true only if the row specifies the correct internal partition, meaning
that the internal partition number is extracted from the row and converted to the external
partition number for the corresponding level, rather than actually recalculating it from the
partitioning columns of a row.
SQL Reference: Data Definition Statements
107
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
A query that selects rows WHERE PARTITION#Ln <> partitioning_expression_n,
where the value of n is the same on both sides of the inequality,25 only returns rows that
are not properly partitioned. In other words, the query does not return any rows if things
are working correctly.
If the query returns rows, you must revalidate the table (see “General Rules for the
REVALIDATE PRIMARY INDEX Option” on page 117).
Rules For Altering the Partitioning Expression For a Primary Index
The following general rules and observations apply to the MODIFY PRIMARY INDEX option
of the Primary Index Options Clause when you alter partitioning expressions (also see “Rules
and Guidelines for Adding and Dropping Ranges in a Partitioning Expression” on page 111):
•
If statistics, whether single-column or multicolumn, have been collected on the
system-derived PARTITION column of a PPI table, you must drop those statistics before
you can alter the partitioning expression for the table.
The high-level procedure for altering the partitioning expression of a PPI table is as
follows:
•
a
Drop the statistics on the system-derived PARTITION column.
b
Alter the partitioning expression.
c
Recollect PARTITION statistics.
d
End of procedure.
You can write any valid SQL expression as a partitioning expression with the following
exclusions:
•
Expressions that require comparisons of CHARACTER or GRAPHIC data to be
evaluated. Such comparisons use the following operators in their evaluation:
• =
• <=
• >
• BETWEEN
• <
• LIKE
• >=
•
•
CHARACTER and GRAPHIC comparison functions such as the following:
• CHAR2HEXINT
• TRANSLATE
• INDEX
• TRANSLATE_CHK
• LOWER
• TRIM
• MINDEX
• UPPER
• POSITION
• VARGRAPHIC
User-defined functions
25. The value of n must be an integer value that ranges between 1 and 15, inclusive.
108
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
•
Aggregate functions
•
Grouped row ordered analytic functions
•
Built-in functions
•
The RANDOM function
•
The HASHAMP and HASHBAKAMP functions26
•
The system-derived PARTITION column
•
The UPPERCASE attribute
•
Set operators
•
Subqueries
If the data type for the result of partitioning_expression is not INTEGER, then the value is
implicitly cast to the INTEGER type.
If the result type cannot be cast to INTEGER, then an error is returned.
•
If partitioning_expression is only a CASE_N function, then the number of conditions
defined must be less than or equal to 65,53327 (see the description of CASE_N in SQL
Reference: Functions and Operators).
•
If partitioning_expression is only a RANGE_N function, then the number of ranges defined
for the function must be less than or equal to 65,5332 (see the description of RANGE_N in
SQL Reference: Functions and Operators).
•
The system derives a table-level index CHECK constraint from the partitioning
expressions (see “General Rules for the MODIFY PRIMARY INDEX Option” on
page 102). The text for this derived constraint cannot exceed 8,192 characters.
•
If you do not specify a WITH phrase, then a new partitioning expression for all rows
currently in the table must, after casting to INTEGER if it is not already typed as
INTEGER, generates a non-null value between 1 and 65,535.
Otherwise, an error is returned.
•
If you specify a WITH DELETE phrase, then any row for which a new partitioning
expression does not generate, after casting to INTEGER if it is not already typed as
INTEGER, a non-null value between 1 and 65,535 is deleted.
•
If you specify a WITH INSERT [INTO] save_table phrase for a base table whose PPI is
defined using the RANGE_N function, after casting to INTEGER if it is not already typed
as INTEGER, a non-null value between 1 and 65,535, is deleted from the table and
inserted into save_table.
•
save_table cannot be the same table as table_name or an error is returned.
•
save_table must have the same number of columns with compatible data types as
table_name, otherwise an error is returned.
26. HASHROW and HASHBUCKET are permitted.
27. When ranges are defined explicitly (not using an EACH clause), then other size limits such as those for
table headers, request text, implied constraint checks, or EVL code, are likely to be reached before you
exceed the limit of 65 533 conditions.
SQL Reference: Data Definition Statements
109
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
•
If errors occur inserting into save_table, then the following rollback behavior occurs,
depending on the session mode in effect:
IF the session is in this session mode …
THEN the following block of work is rolled back …
ANSI
request.
Teradata
transaction.
If a new partitioning expression is defined with a NO RANGE partition, by definition
this partition contains any row that does not fall into an explicitly defined partitioning
expression value range (see the description of the RANGE_N function in SQL
Reference: Functions and Operators for an explanation of the function of the NO
RANGE partition). As a result, once a range partition is dropped, any row that had
been assigned to that partition must then be assigned to the NO RANGE partition. See
“Example 50: Dropping a Partition From a PPI Table When the PPI Is Defined Using
The RANGE_N Function and NO RANGE Is Specified” on page 134 for an example of
how this works.
•
If evaluation of a new partitioning expression for a row causes evaluation errors (such as
divide by zero), then any changes made to the table or to save_table are rolled back and the
primary index is not changed.
•
The new partitioning expressions become the effective partitioning expressions for the
primary index as soon as the table is altered successfully.
•
If there is a subsequent attempt to insert or update a row of a PPI table such that the
partitioning expression for that row does not generate, after casting to INTEGER if it is not
already typed as INTEGER, a non-null value between 1 and 65,535, then an error is
returned for the insert or update operation.
•
Increasing the number of active partitions might degrade the performance of primary
index accesses and joins, but allows for finer partition elimination (see Database Design for
details).
Rules for Altering the Partitioning Expression for a Multilevel Partitioned
Primary Index
The following rules apply only to altering the partitioning expression for a multilevel
partitioned primary index. Note that all the rules described in “Rules For Altering the
Partitioning Expression For a Primary Index” on page 108, with one exception, are a superset
and also apply to multilevel PPIs.
•
Each new partitioning expression must consist only (after removal of any extraneous
parentheses around the function reference) of either a RANGE_N function or a CASE_N
function.
It is not required that the partitioning expressions for a PPI table be all of one form or the
other, only that each individual partitioning expression must be constructed from either a
RANGE_N or a CASE_N function only.
110
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
The product of the number of partitions defined by each new partitioning expression
cannot exceed 65,535.
This rule implies that the maximum number of new partitioning expressions is 15.28
•
Each new partitioning expression must define at least two partitions.
This rule also implies that the maximum number of new partitioning expressions is 15.
If more than two partitions are defined at one or more levels, the number of new
partitioning expressions can be further limited.
Rules and Guidelines for Adding and Dropping Ranges in a Partitioning
Expression
The following rules and guidelines apply to the DROP RANGE and ADD RANGE options.
Note that these rules only allow modification of RANGE_N partitioning expressions already
defined for the table: they do not allow for dropping or adding a partitioning expression. In
other words, you cannot use these options to change the number of partitioning levels.
To change the number of partitioning levels, modify a CASE_N partitioning expression, or
modify a partitioning expression that is neither solely a RANGE_N nor solely a CASE_N
function,29 you must use the PARTITION BY clause in the ALTER TABLE statement to specify
all the desired partitioning expressions and the table must be empty.
If that is not possible, or if the reorganization of partitions would cause too many rows to be
moved from their current partition to a different partition, use a CREATE TABLE request to
create a new table with the partitioning you want, then use an INSERT … SELECT or MERGE
request with error logging to move the rows from the source table into the newly created target
table with the desired partitioning.
See SQL Reference: Data Manipulation Statements for information about the
INSERT … SELECT and MERGE statements and their LOGGING ERRORS option, and
“CREATE ERROR TABLE” on page 205 for information about error tables.
•
Have a well-defined, preferably automated, process for scheduling and issuing ALTER
TABLE requests to add and drop partitioning ranges.
•
Define enough future ranges30 to minimize the frequency of ALTER TABLE requests for
adding and dropping partitions.
If you perform this task too infrequently, you might forget to make the necessary range
drops and additions, and the process might fail because it does not occur frequently
enough.
28. This is because 216 = 65,536, which is one larger than the valid upper limit on the number of partitioning
expressions for a table.
29. This type of partitioning expression is only valid for single-level partitioning. All multilevel partitioning
expressions must be defined solely on a RANGE_N function or solely on a CASE_N function. The two
functions can be mixed within a partitioning expression, with each representing solely one or more levels
of the expression.
30. A future range is a range over date values that have not yet occurred at the time the partition is added.
SQL Reference: Data Definition Statements
111
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Consider the following guidelines:
•
It is generally better to perform this task monthly rather than yearly.
•
You should keep the number of “future” ranges at any one time to less than 10 percent
of the total number of defined partitions.
As always, you must tune the process to suit your individual processes, query workloads,
and performance criteria. Running and comparing periodic EXPLAIN reports is useful for
determining the effects of your current partitioning on the performance of individual
queries from your standard workloads.
•
Ensure that you drop old partitions that are no longer needed, especially if queries in the
workloads that access the PPI table do frequent primary index accesses and joins and the
complete partitioning column set is not included in the primary index definition.
•
You can alter partitioning by explicitly specifying new partitioning expressions only if the
PPI table is empty.
•
If you specify DROP RANGE in the first alter partitioning expression, it is equivalent to
DROP RANGE#L1.
Otherwise, it is equivalent to DROP RANGE [#Ln] where n is one more than the level
associated with the preceding alter partitioning expression.
•
If you specify DROP RANGE [#Ln] in other than the first alter partitioning expression, n
must be at least one greater than the default or specified level associated with the preceding
alter partitioning expression; otherwise, the system aborts the request and returns an error
to the requestor.
•
The default or specified level for DROP RANGE [#Ln] must not exceed the number of
partitioning expressions currently defined for the primary index of the table; otherwise,
the system aborts the request and returns an error to the requestor.
•
If you specify ADD RANGE with a DROP RANGE [#Ln] in an alter partitioning
expression, it is equivalent to ADD RANGE #Ln, where n is the same as the default or
specified level of that DROP RANGE [#Ln].
•
If you specify ADD RANGE [#Ln] with a DROP RANGE [#Ln] in an alter partitioning
expression, n must specify the same level as the default or specified level of that DROP
RANGE [#Ln]; otherwise, the system aborts the request and returns an error to the
requestor.
•
If you specify ADD RANGE without a DROP RANGE [#Ln] in the first alter partitioning
expression, it is equivalent to ADD RANGE #L1.
Otherwise, it is equivalent to ADD RANGE [#Ln], where n is one more than the level
associated with the preceding alter partitioning expression.
112
•
If you specify ADD RANGE [#Ln] without a DROP RANGE [#Ln] in other than the first
alter partitioning expression, n must be at least one more than the default or specified level
associated with the preceding alter partitioning expression; otherwise, the system aborts
the request and returns an error to the requestor.
•
The default or specified level for ADD RANGE [#Ln] must not exceed the number of
partitioning expressions currently defined for the primary index of the table; otherwise,
the system aborts the request and returns an error to the requestor.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
If you specify WITH DELETE, there must be a DROP RANGE [#Ln] in at least one of the
alter partitioning expressions; otherwise, the system aborts the request and returns an
error to the requestor.
•
If you specify WITH INSERT, there must be a DROP RANGE [#Ln] in at least one of the
alter partitioning expressions; otherwise, the system aborts the request and returns an
error to the requestor.
•
For a single-level partitioned primary index, a partition conditional expression must be a
conditional expression that references either the system-derived column PARTITION or
the system-derived column PARTITION#L1, but not both, and no other columns;
otherwise, the system aborts the request and returns an error to the requestor.
If the table includes an explicit column named PARTITION, you cannot use PARTITION
in the conditional expression; otherwise, the system aborts the request and returns an
error to the requestor.
If the table includes an explicit column named PARTITION#L1, you cannot use
PARTITION#L1 in the conditional expression.
•
For a multilevel partitioned primary index, a partition conditional expression must be a
conditional expression that references the system-derived column PARTITION#Ln, where
n is the same as the default or specified level of the corresponding DROP RANGE [#Ln]
and no other columns; otherwise, the system aborts the request and returns an error to the
requestor.
If the table includes an explicit column named PARTITION#Ln, this WHERE form cannot
be used; otherwise, the system aborts the request and returns an error to the requestor.
Note that you cannot specify the system-derived column PARTITION in the conditional
expression.
•
If you specify DROP RANGE [#Ln] or ADD RANGE [#Ln], the corresponding
partitioning expression at the default or specified level of this DROP RANGE [#Ln] or
ADD RANGE [#Ln] must be partitioned by a partitioning expression that consists only31
of a RANGE_N function. The expression cannot be defined with a BLOB, CLOB, or
BIGINT data type.
Otherwise, the system aborts the request and returns an error to the requestor.
•
The conditional expression in a DROP RANGE WHERE clause must reference the
system-derived columns PARTITION (or PARTITION#Ln for an MLPPI) and no other
columns.
If the table you are attempting to modify has a user-defined column named PARTITION
or PARTITION#Ln, where n is an integer ranging from 1 to 15, inclusive, then this syntax
is not valid and returns an error.
31. After removal of any extraneous parentheses around the function reference.
SQL Reference: Data Definition Statements
113
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
•
Each range specified for a start_expression or end_expression must conform to the rules of a
RANGE_N function (see SQL Reference: Functions and Operators for details). For example,
the following rules must be observed:
•
A range value must be compatible in data type with the test expression that defines the
corresponding existing partitioning expression for the table.
•
The ranges must be in sequential order and cannot overlap one another.
•
The last range of a range expression sequence must specify an ending range and be
preceded by the keyword AND.
•
Not all data types are not supported for the test expression or in the start and end
expressions. See SQL Reference: Functions and Operators for details.
You can specify either an OR UNKNOWN clause or an UNKNOWN clause for a range
expression sequence, but not both.
If you specify both, the system returns an error.
•
An ALTER TABLE request that specifies DROP RANGE [#Ln] or ADD RANGE [#Ln]
options, or both, is equivalent to the following generalized ALTER TABLE statement
syntax expressed in pseudo-BNF format:
ALTER TABLE table_name
MODIFY [[NOT] UNIQUE] PRIMARY INDEX [index_name | NOT NAMED]
[(primary_index_column_list)]
PARTITION BY { new_partitioning_expression
|(new_partitioning_expression
{, new_partitioning_expression}…) }
[null_partition_handler];
where:
•
114
•
table_name, null_partition_handler, and other options are the same as for the original
ALTER TABLE request.
•
null_partition_handler refers to a WITH INSERT | DELETE clause.
•
The number of new partitioning expressions is the same as the number of existing
partitioning expressions for the table.
Each new partitioning expression is the same as the existing partitioning expression for
that level except as noted in the following four points:
•
If you specify DROP RANGE [#Ln] WHERE partition_conditional_expression for that
level, then the new partitioning expression for that level does not include the specified
existing ranges/partitions where the partition conditional expression is true.
•
If you specify DROP RANGE [#Ln] alter_ranges for that level, then the new
partitioning expression for that level does not include the specified ranges and
partitions in the alter ranges.
•
If you specify ADD RANGE [#Ln] alter_ranges for that level, then the new partitioning
expression for that level includes the addition of the new ranges and partitions merged
in order with the existing ranges after first applying the DROP RANGE [#Ln] clause if
one is specified.
•
The resulting new partitioning expression for a level must consist of at least one range;
otherwise, the system aborts the request and returns an error to the requestor.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
For multilevel partitioning, the resulting new partitioning expressions must each
define at least two partitions; otherwise, the system aborts the request and returns an
error to the requestor.
•
new_partitioning_expression is the same as the corresponding existing partitioning
expression except for the following properties:
•
If you specify DROP RANGE [#Ln] WHERE partition_conditional_expression for that
level, then the new partitioning expression for that level does not include the specified
existing ranges/partitions where the partition conditional expression is true.
The system returns an error if partition_conditional_expression evaluates to unknown
for an existing range.
•
If you specify DROP RANGE [#Ln] alter_ranges for that level, then the new
partitioning expression for that level does not include the specified ranges and
partitions in the range sequence.
The specified ranges and partitions must match existing ranges (after expansion with
EACH clauses in both the old partitioning expression and the DROP RANGE clause)
and partitions; otherwise, an error is returned.
For ranges to match, their start and end must match. A dropped range that spans
multiple existing ranges is not considered to be a match.
•
If you specify ADD RANGE [#Ln] alter_ranges for that level, then the new partitioning
expression for that level includes the addition of the new ranges and partitions merged
in order with the existing ranges after first applying the DROP RANGE [#Ln] clause if
one is specified.
The ranges cannot overlap with any of the existing ranges after first applying the
DROP RANGE clause or an error is returned.
If you add partitions, they must not conflict with or be the same as existing partitions
after first applying the DROP RANGE clause or an error is returned.
•
Dropping a range or partition does not necessarily cause rows to be deleted. Affected rows
could be moved to an added range or to the optional NO RANGE [OR UNKNOWN] or
UNKNOWN partitions.
•
Two general guidelines for adding and dropping ranges:
•
•
Do not overlap new ranges with dropped ranges. For example, do not:
•
DROP two ranges and ADD one range that covers both of the original two ranges.
•
DROP up to all but one range and ADD back new ranges.
DROP RANGE … WITH DELETE and DROP RANGE … WITH INSERT INTO
save_table do not necessarily delete rows in the dropped ranges.
The reasons why this is true are as follows:
•
DROP RANGE and ADD RANGE modify an existing partitioning expression to create
a new partitioning expression for the table.
The system deletes rows only if they do not satisfy this new partitioning expression.
•
If the new partitioning expression specifies the NO RANGE option, then no rows are
deleted.
SQL Reference: Data Definition Statements
115
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
Rows can be moved from their current partition to any of the following:
•
•
Newly added range partitions.
•
The NO RANGE partition.
•
The NO RANGE OR UNKNOWN partition.
Similarly, rows can be moved from the NO RANGE partition to newly added range
partitions.
If you truly want to delete the rows of a partition for the situation where they have other
partitions they could be moved into,32 use a DELETE request to remove them from the
table before you alter its partitioning expressions.
•
The resulting new partitioning expression for a level must define at least one range;
otherwise, the system aborts the request and returns an error to the requestor.
For multilevel partitioning, the resulting new partitioning expressions must each define at
least two partitions; otherwise, the system aborts the request and returns an error to the
requestor.
IF a new partitioning expression
corresponds to this level …
THEN …
1
the number of partitions defined must be less than or equal
to the previously defined maximum.
2 or higher
it must define the same number of partitions.
Rules for Retaining Eligibility for Restoring or Copying Selected Partitions
While you can change some of the characteristics of a table and retain the ability to restore or
copy selected partitions to it, other operations against a PPI table render it unable to be the
target of selected partition restorations.
The following table definition changes do not invalidate future restorations of selected
partitions for the targeted or referenced tables:
•
Altering table-level options that are not related to the semantic integrity of the table,
including the following:
•
Fallback protection (see “FALLBACK and JOURNAL Defaults” on page 73 and
“ALTER TABLE and FALLBACK” on page 73).
•
Journaling attributes (see “Journaling” on page 78).
•
Free space percentage (see “DEFAULT FREESPACE” on page 77).
•
Data block size (see “IMMEDIATE DATABLOCKSIZE” on page 77).
Also see “CREATE TABLE (Table Options Clause)” on page 680 for more information
about these options.
•
Altering the partitioning expression. See “Rules For Altering the Partitioning Expression
For a Primary Index” on page 108 and “CREATE TABLE (Index Definition Clause)” on
page 716 for more information about these options.
32. Such as NO RANGE, NO RANGE OR UNKNOWN, UNKNOWN, or a newly added partition.
116
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
Altering either column-level or table-level CHECK constraints. See “Adding and Dropping
CHECK Constraints” on page 87 and “CREATE TABLE (Column Definition Clause)” on
page 685 for more information about these options.
When the target and source are different systems, you must repeat each of the previously listed
operations on the affected tables of the target system to ensure that the two are kept in
synchrony.
The following ALTER TABLE operations do make any future restore or copy operations of
selected partitions for targeted or referenced tables non-valid:
•
Adding or dropping columns (see “Dropping Columns From a Table” on page 75 and
“Adding Columns To a Table” on page 76).
•
Altering the definition of existing columns (excluding the exceptions noted in the previous
list).
•
Adding, dropping, or modifying referential integrity relationships between tables (see
“Adding or Dropping Referential Integrity Constraints” on page 88).
See Database Administration and Teradata Archive/Recovery Utility Reference for complete
warnings, procedures, and other information related to partial restoration of PPI partitions.
General Rules for the REVALIDATE PRIMARY INDEX Option
REVALIDATE PRIMARY INDEX regenerates table headers for a PPI in the specified table or
noncompressed join index and optionally verifies the partitioning of its rows. If partitioning
errors are detected for a table (but not a join index), they are then corrected.
You might need to revalidate a PPI when any of the following conditions exist:
•
The table headers for a table or noncompressed join index with a partitioned primary
index are marked as nonvalid.
This is most often found after an upgrade or after restoring or copying a table to a system
having a different operating system or different hardware.
•
The RoundHalfwayMagUp setting in the DBSControl record is changed and a partitioning
expression includes decimal operations.
A change in decimal rounding rules can cause the partitioning expression to evaluate
differently.
If this occurs for a noncompressed join index, drop the index and then recreate it (see
“CREATE JOIN INDEX” on page 346).
•
The table is restored or copied to another system that has a different
RoundHalfwayMagUp setting in its DBSControl record and the partitioning expression
for a table includes decimal operations.
A change in decimal rounding rules can cause the partitioning expression to evaluate
differently.
•
The table is restored or copied to another system and the partitioning expression includes
floating point operations.
Floating point calculations might cause the partitioning expression to evaluate differently
on different systems.
SQL Reference: Data Definition Statements
117
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
The table is restored or copied to another system that has a different hashing algorithm
and the partitioning expression includes a HASHROW or HASHBUCKET function.
A different hashing function can cause the partitioning expression to evaluate differently.
•
Teradata Database is upgraded in such a way that the calculation of the partitioning
expressions for tables and noncompressed join indexes change.
•
The CheckTable utility or valid SQL queries indicate rows with incorrect internal partition
numbers or rows in the wrong partition for the table.
If this occurs unexpectedly, please report the problem to the GSC immediately.
If this occurs for a noncompressed join index, drop the index and then recreate it (see
“CREATE JOIN INDEX” on page 346).
The following rules apply to the REVALIDATE PRIMARY INDEX option:
•
The primary index for the table or noncompressed join index must be a partitioned
primary index.
Otherwise, the system returns an error.
•
If you specify neither a WITH DELETE nor a WITH INSERT phrase for the option, then
only table headers are regenerated and no error checking or repair is performed.
•
If you specify either a WITH DELETE or a WITH INSERT phrase, then in addition to
regenerating the table headers for the table, all the rows in a base table are validated for
their partition number and row hash value.
You cannot specify a WITH DELETE or WITH INSERT clause when you revalidate a join
index. If you attempt to do so, the request aborts and the system returns an error message
to the requestor.
If you suspect or detect a problem with the rows of a noncompressed join index, you must
drop and then recreate it.
118
•
If you specify a WITH DELETE phrase, then any row for which a partitioning expression
does not generate a nonnull value between 1 and 65,535 (after casting to INTEGER if the
value is not already typed as INTEGER) is deleted.
•
If you specify a WITH INSERT [INTO] save_table phrase, any row for which a
partitioning expression does not generate a non-null value between 1 and 65,535 (after
casting to INTEGER if the value is not already typed as INTEGER) is deleted from the
table and inserted into save_table.
•
save_table cannot be the same table as table_name or an error is returned.
•
save_table must have the same number of columns with compatible data types as
table_name, otherwise an error is returned.
•
If errors occur inserting into save_table, then the following rollback behavior occurs,
depending on the session mode in effect:
IF the session is in this mode …
THEN the following block of work is rolled back …
ANSI
request.
Teradata
transaction.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
•
If evaluation of a partitioning expression for a row causes evaluation errors (such as divide
by zero), then any changes made to the table or to save_table are rolled back and the
primary index is not changed.
Specific rollback behavior depends on the session mode in effect:
IF the session is in this mode …
THEN the following block of work is rolled back …
ANSI
request.
Teradata
transaction.
If this occurs, you should correct the problem using one of the following solutions:
•
•
Make the primary index for the table or noncompressed join index an NPPI.
•
Change the partitioning expression to one that does not generate evaluation errors.
•
Delete rows that cause evaluation errors.
•
Drop the table.
For the remaining rows in the table, the internal partition number and row hash are
updated as needed and, if the row is not in the correct partition or row hash, it is moved to
the correct location.
Rows that are out of order by their assigned ROWID are not corrected and an error is
returned.
•
Any secondary indexes, join indexes, or hash indexes defined on the table are updated as
needed.
•
The values of the system-derived PARTITION column might change for the rows in the
table.
When you revalidate a table, its version number is incremented because its structure is
altered. When the version number changes, you cannot perform any of the following
actions over a DDL statement that alters table structure:
•
Cluster restore
•
Single AMP restore
•
Rollforward or rollback of a permanent journal
If the ARC utility encounters such a structural table change during a rollforward or
rollback operation, then that operation is stopped and an error message is returned in the
output listing.
Revalidating the Primary Index of PPI Tables and Join Indexes With a
HASH Function Partitioning Expression After a Cross Platform Migration
During the cross platform migration process, the table headers for PPI tables and join indexes
are regenerated by the post_data_restore script after they are restored or copied to a different
system.
If the new system has either a different hashing algorithm or 20-bit hash buckets rather than
16-bit hash buckets, a change in the value returned by a hash function can cause the
partitioning expression to evaluate differently, and the regenerated table headers can cause
SQL Reference: Data Definition Statements
119
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
incorrect query results to be returned from PPI tables and join indexes when a partitioning
expression in the table is specified using the HASHBUCKET function (see SQL Reference:
Functions and Operators for documentation of the HASHBUCKET function).
When this occurs, you must revalidate the primary index of any affected tables using the
following procedure.
1
Identify the PPI tables and join indexes affected by this problem by running the
pre_upgrade_prep.pl script prior to the migration. You should then run the
hashbucket_ppi.rpt script afterward.
Among other things, pre_upgrade_prep.pl performs a SELECT request that finds and
reports any tables or join indexes that must be revalidated after the migration occurs.
If you want to submit a standalone SELECT request to return the rows that must be
revalidated, you can submit the following request, which duplicates the request the
pre_upgrade_prep.pl script submits.
SELECT
FROM
TRIM(DataBasenamei)||'.'||TRIM(TVMNamei), TableKind
DBC.TableConstraints AS TC
JOIN
DBC.TVM
ON
TC.TVMID = TVM.TVMID
JOIN
DBC.Dbase
ON
TC.DBaseId = Dbase.DatabaseId
WHERE
ConstraintType = 'Q'
AND
UPPER(TableCheck) LIKE '%HASHBUCKET%'
ORDER BY 1;
2
Revalidate the rows in each of the data tables identified by pre_upgrade_prep.pl (but not
the join index rows) the script returns using the following procedure.
a
Create a save table using the DDL for the affected PPI table, but do not specify any
partitioning or secondary indexes.
b
Submit the following ALTER TABLE request to revalidate the PPI for table_name.
ALTER TABLE database_name.table_name
REVALIDATE PRIMARY INDEX
WITH DELETE/INSERT [INTO] save_table
where:
Syntax element …
Specifies the name of the …
database_name
database or user that contains table_name.
table_name
affected PPI table.
save_table
table created in step a of this procedure.
This revalidation requires the null partition handler specified by save_table to ensure
that rows are stored in the correct partitions.
120
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
c
The following table outlines your choices at this step of the procedure.
IF save_table …
THEN …
is not populated
the revalidation process is complete.
is populated
you have a choice of how to handle each row in save_table:
• Redefine the partitioning of the original PPI table so you can reinsert
the row.
OR
• Save the row in a separate table.
d
After successfully handling each of the rows in save_table, drop the table.
e
Revalidate the join index rows by dropping and then recreating each affected index.
f
End of procedure.
Example 1: Add Columns to a Table
Use the following to add the columns street and city to the employee table:
ALTER TABLE Employee
ADD street VARCHAR(30),
ADD city
VARCHAR(20);
Example 2: Add Fallback to a Table
Use the following to implement fallback protection for the employee table:
ALTER TABLE employee,
FALLBACK;
Example 3: Add a Single Before-Image Journal and Dual After-Image
Journal
If a table named newemp is set for no journaling, but the database has a defined journal, the
following statement could be used to add a single before-image journal and a dual after-image
journal:
ALTER TABLE newemp,
BEFORE JOURNAL, DUAL AFTER JOURNAL;
Example 4: Change a Single Before-Image Journal to a Dual Before-Image
Journal and Drop Two Columns
The following request changes the single before image journal to a dual image journal and also
drops two columns:
ALTER TABLE newemp,
DUAL BEFORE JOURNAL
DROP phone,
DROP pref;
SQL Reference: Data Definition Statements
121
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 5: Add a TITLE Phrase
The following example changes the attributes of the deptno column in the department table to
include a TITLE phrase:
ALTER TABLE personnel.department
ADD deptno TITLE ’Depart’;
Example 6: Add the Null Attribute to Columns
The following statements add the NULL qualifier to columns training_skill and column_2:
ALTER TABLE personnel
ADD training_skill NULL;
ALTER TABLE abc
ADD column_2 NULL;
Example 7: Composite Changes: NULL to NOT NULL
A composite change to a column implies changing more than one attribute of that column in
one statement. NULL columns can be changed to NOT NULL, along with other attribute
changes, in one statement. The following example changes both the case and NULL attribute
of column_2. An error is returned if abc contains any rows with nulls in column_2.
ALTER TABLE abc
ADD column_2 CASESPECIFIC NOT NULL;
Example 8: Composite Changes: NOT NULL to NULL
Composite changes to columns that involve changing the NOT NULL attribute to NULL are
not valid. For example, the following cannot be done:
ALTER TABLE abc
ADD column_2 TITLE ‘newname’ NULL;
To make these changes, you must perform two separate ALTER TABLE statements:
ALTER TABLE abc ADD column_2 TITLE ‘newname’;
ALTER TABLE abc ADD column_2 NULL;
Example 9: DATABLOCKSIZE
The following ALTER TABLE statement changes the maximum data block size of 130,560
bytes (255 sectors) and repacks existing data into blocks of that size:
ALTER TABLE employee,
DATABLOCKSIZE = 130560 BYTES IMMEDIATE;
Example 10: FREESPACE
The following ALTER TABLE statement changes the freespace to 5 percent:
ALTER TABLE employee,
FREESPACE = 5 PERCENT;
122
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 11: CHECKSUM
The following ALTER TABLE statement changes the disk I/O integrity checksum value to the
system default:
ALTER TABLE employee,
CHECKSUM = DEFAULT;
Example 12: CHECKSUM
The following ALTER TABLE statement changes the disk I/O integrity checksum value to
HIGH and updates the existing checksums immediately:
ALTER TABLE employee,
CHECKSUM = HIGH IMMEDIATE;
Example 13: Changing The Compression Value For An Existing Compressed
Column
Suppose a company that does business only in Santa Monica decides to expand, and while
previously the city name Santa Monica was compressed, it now makes more sense for the city
name Los Angeles to be compressed. The following example changes the single compressed
city name value from Santa Monica to Los Angeles, which also means that it should also be
compressed:
ALTER TABLE customer
ADD city_name COMPRESS ‘Los Angeles’;
If city_name had not been compressed previously, this statement would compress all
occurrences of Los Angeles. Note, too, that this is an extremely artificial example, because you
could just as well have compressed both Santa Monica and Los Angeles.
Example 14: NO COMPRESS For A New Column
The following example adds a column named qty_shipped_2006 to the customer table and
makes that column uncompressible.
ALTER TABLE customer
ADD qty_shipped_2006 NO COMPRESS;
Example 15: Add a New Column With Multivalued Compression
The following ALTER TABLE statement adds a new compressible column and specifies the
maximum number of distinct values for compression:
SQL Reference: Data Definition Statements
123
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
ALTER TABLE mkw.x
ADD b CHARACTER(2)
COMPRESS (
'a1','a2','a3','a4','a5','a6','a7','a8','a9','a10',
'b1','b2','b3','b4','b5','b6','b7','b8','b9','b10',
'c1','c2','c3','c4','c5','c6','c7','c8','c9','c10',
'd1','d2','d3','d4','d5','d6','d7','d8','d9','d10',
'e1','e2','e3','e4','e5','e6','e7','e8','e9','e10',
'f1','f2','f3','f4','f5','f6','f7','f8','f9','f10',
'g1','g2','g3','g4','g5','g6','g7','g8','g9','g10',
‘h1','h2','h3','h4','h5','h6','h7','h8','h9','h10',
'i1','i2','i3','i4','i5','i6','i7','i8','i9','i10',
'j1','j2','j3','j4','j5','j6','j7','j8','j9','j10',
'k1','k2','k3','k4','k5','k6','k7','k8','k9','k10',
'l1','l2','l3','l4','l5','l6','l7','l8','l9','l10',
'm1','m2','m3','m4','m5','m6','m7','m8','m9','m10',
'n1','n2','n3','n4','n5','n6','n7','n8','n9','n10',
'o1','o2','o3','o4','o5','o6','o7','o8','o9','o10',
'p1','p2','p3','p4','p5','p6','p7','p8','p9','p10',
'q1','q2','q3','q4','q5','q6','q7','q8','q9','q10',
'r1','r2','r3','r4','r5','r6','r7','r8','r9','r10',
's1','s2','s3','s4','s5','s6','s7','s8','s9','s10',
't1','t2','t3','t4','t5','t6','t7','t8','t9','t10',
'u1','u2','u3','u4','u5','u6','u7','u8','u9','u10',
'v1','v2','v3','v4','v5','v6','v7','v8','v9','v10',
'w1','w2','w3','w4','w5','w6','w7','w8','w9','w10',
'x1','x2','x3','x4','x5','x6','x7','x8','x9','x10',
'y1','y2','y3','y4','y5','y6','y7','y8','y9','y10',
'z1','z2','z3','z4',’z5’);
Example 16: Renaming a Column, Then Adding a New Column Using the
Previous Name of the Renamed Column
When the need arises, you can rename an existing column, then create a new column, perhaps
with a completely different data type, using the old name of the renamed column. For
example, suppose you have the following table definition:
CREATE SET TABLE t1, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL,
upi INTEGER NOT NULL,
f1 FLOAT,
d1 DECIMAL(7,2),
i1 INTEGER)
UNIQUE PRIMARY INDEX (upi);
Suppose you decide to rename column f1 as f2 and then add a new column named f1 having
the INTEGER data type rather than the FLOAT data type previously associated with the
column now named f2:
ALTER TABLE t1
RENAME f1 AS f2,
ADD
f1 INTEGER;
*** Table has been modified.
*** Total elapsed time was 1 second.
124
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
You then also decide to rename column i1 as i2 and then add a new column named i1 having
the DECIMAL data type rather than the INTEGER data type previously associated with the
column now named i2:
ALTER TABLE t1
RENAME i1 AS i2,
ADD
i1 DECIMAL(8,3);
*** Table has been modified.
*** Total elapsed time was 1 second.
You then display the new table definition using the SHOW TABLE statement (see “SHOW
CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/ SHOW JOIN
INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/ SHOW REPLICATION
GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/ SHOW VIEW” on page 1590):
SHOW TABLE t1;
*** Text of DDL statement returned.
*** Total elapsed time was 1 second.
CREATE SET TABLE DF2.t1, NO FALLBACK,NO BEFORE JOURNAL,
NO AFTER JOURNAL,CHECKSUM = DEFAULT (
upi INTEGER NOT NULL,
f2 FLOAT,
d1 DECIMAL(7,2),
i2 INTEGER,
f1 INTEGER,
i1 DECIMAL(8,3)
UNIQUE PRIMARY INDEX (upi);
Example 17: Add a PRIMARY KEY Constraint
table_1 must not already have a defined PRIMARY KEY constraint. Constraint name
primary_1 must not duplicate an existing name in table_1.
ALTER TABLE table_1
ADD CONSTRAINT primary_1 PRIMARY KEY (field_1, field_2);
Field_1 and field_2 must be NOT NULL or an error is returned.
Example 18: Add a Named CHECK Constraint
Constraint name check_1 must not be an existing name in table_1.
ALTER TABLE table_1 ADD CONSTRAINT check_1
CHECK (field_1 > field_2);
Example 19: Add a Named UNIQUE Constraint
Constraint name unique_1 must not be an existing name in table_1.
ALTER TABLE table_1
ADD CONSTRAINT unique_1
UNIQUE (field_1, field_2);
SQL Reference: Data Definition Statements
125
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 20: Add a Named FOREIGN KEY Constraint
Constraint name reference_1 must not be an existing name in table_1.
ALTER TABLE table_1
ADD CONSTRAINT reference_1
FOREIGN KEY (field_1) REFERENCES table_2;
Example 21: Drop a Named CHECK Constraint
Constraint name check_1 must exist in table_1.
ALTER TABLE table_1
DROP CONSTRAINT check_1;
Example 22: Drop a Named CHECK Constraint
Constraint name check_1 must exist in table_1 as a CHECK constraint.
ALTER TABLE table_1
DROP CONSTRAINT check_1
CHECK;
Example 23: Drop a UNIQUE Constraint
Constraint name unique_1 must exist in table_1.
ALTER TABLE table_1
DROP CONSTRAINT unique_1;
126
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 24: Drop a Named Constraint
Constraint name reference_1 must exist in table_1.
ALTER TABLE table_1
DROP CONSTRAINT reference_1;
Example 25: Modify a Named CHECK Constraint
Replace the current definition for CHECK constraint check_1 with the new definition.
Constraint name check_1 must be an existing CHECK constraint.
ALTER TABLE table_1
MODIFY CONSTRAINT check_1
CHECK (field_2 > 0);
Example 26: Add an Unnamed CHECK Constraint
The following statement adds an unnamed CHECK constraint to ensure that values in
column field_2 are always greater than 100:
ALTER TABLE table_1
ADD CHECK (field_2 > 100);
Example 27: Add a Column With an Unnamed CHECK Constraint
The following statement adds an unnamed CHECK constraint to ensure that values in
column field_1 are always greater than 0.
This example is valid only if there is not an existing unnamed column level CHECK for field_1
in table_1.
ALTER TABLE table_1
ADD field_1
CHECK (field_1 > 0);
Example 28: Add a Multicolumn Unnamed UNIQUE Constraint
The following statement adds an unnamed uniqueness constraint to the columns named
field_3 and field_4:
ALTER TABLE table_1
ADD UNIQUE (field_3, field_4);
Example 29: Add a FOREIGN KEY Constraint
The following statement adds a foreign key constraint on the column named field_2 in
table_1:
ALTER TABLE table_1
ADD FOREIGN KEY (field_2) REFERENCES table_3;
SQL Reference: Data Definition Statements
127
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 30: Drop All Unnamed Table-Level CHECK Constraints
This example drops all unnamed table-level CHECK constraints.
ALTER TABLE table_1
DROP CHECK;
Example 31: Drop an Unnamed Column-Level CHECK Constraint
This example drops the unnamed column level CHECK constraint from column field_1 in
table_1.
ALTER TABLE table_1 DROP field_1
CHECK;
Example 32: Drop a FOREIGN KEY Constraint
This example drops the foreign key constraint on the column named column field_2 in table
table_3.
ALTER TABLE table_1
DROP FOREIGN KEY (field_2) REFERENCES table_3;
Example 33: Add an Unnamed CHECK Constraint
This example modifies column by adding an unnamed CHECK constraint. Column field_1 is
an existing, already constrained field in table_1.
ALTER TABLE table_1
MODIFY field_1
CHECK (field_1 IS NOT NULL);
Example 34: Non-Valid Use of ALTER TABLE With Constraints
The following statement is not valid because you can add or drop only one constraint per
ALTER TABLE statement:
ALTER TABLE table_1
DROP CONSTRAINT check_1,
ADD CONSTRAINT check_2
CHECK (field_2 > 0);
The system returns the following message:
Only a check specification is allowed for the modification.
Example 35: Nonvalid Use of ALTER TABLE With Named Constraints
The following statement is not valid because the constraint named dup_constr_name already
exists in table_1. For this reason, you cannot add it to the table.
ALTER TABLE table_1
ADD CONSTRAINT dup_constr_name
FOREIGN KEY (field_3) REFERENCES table_2;
The system returns the following message:
Constraint with the same name ‘dup_constr_name’ already exists in table.
128
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 36: Nonvalid Use of ALTER TABLE With Named Constraints
The following statement is not valid because the constraint named no_such_constr does not
exist in table_1. For this reason, you cannot modify or drop it.
ALTER TABLE table_1
MODIFY CONSTRAINT no_such_constr
CHECK (field_1 > 0);
Example 37: Nonvalid Use of ALTER TABLE With Named Constraints
The following statement is not valid because the specified constraint does not exist; therefore,
it cannot be dropped.
ALTER TABLE table_1
DROP CONSTRAINT no_such_constr;
The system returns the following message:
The specified constraint name does not exist in table.
Example 38: Add or Drop a Batch Referential Constraint
This example first adds a table-level batch referential constraint to column d1 in table drs.t2
referencing column c1 in table drs.t1 and then drops that same constraint.
CREATE SET TABLE drs.t1, NO FALLBACK,
NO BEFORE JOURNAL,
NO AFTER JOURNAL
(
c1 INTEGER NOT NULL,
c2 INTEGER NOT NULL,
c3 INTEGER NOT NULL)
UNIQUE PRIMARY INDEX (c1);
CREATE SET TABLE drs.t2, NO FALLBACK,
NO BEFORE JOURNAL,
NO AFTER JOURNAL
(
d1 INTEGER,
d2 INTEGER,
d3 INTEGER);
ALTER TABLE drs.t2
ADD CONSTRAINT fpk1
FOREIGN KEY (d1) REFERENCES WITH CHECK OPTION drs.t1 (c1);
ALTER TABLE drs.t2
DROP FOREIGN KEY (d1) REFERENCES WITH CHECK OPTION drs.t1 (c1);
SQL Reference: Data Definition Statements
129
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 39: Adding a Table-Level Referential Constraint
The first statement adds a table-level Referential Constraint relationship on foreign key
column a3 with column e1 in table e. Referential integrity is not enforced for this relationship.
The second statement drops the foreign key Referential Constraint that was created by the
first.
ALTER TABLE a
ADD FOREIGN KEY (a3) REFERENCES WITH NO CHECK OPTION e(e1);
ALTER TABLE a
DROP FOREIGN KEY (a3) REFERENCES e(e1);
CREATE TABLE Request for Examples 40- 47
Examples 42 through 49 assume that the following table has been created:
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
PRIMARY INDEX (o_orderkey)
PARTITION BY RANGE_N(o_orderdate
BETWEEN DATE '1992-01-01'
AND
DATE '1998-12-31'
EACH INTERVAL '1' MONTH)
UNIQUE INDEX (o_orderkey);
Example 40: Nonvalid MODIFY INDEX Requests
The following requests are illegal because they do not specify options that alter the table:
ALTER TABLE orders
MODIFY PRIMARY INDEX;
ALTER TABLE orders
MODIFY NOT UNIQUE PRIMARY INDEX;
Example 41: Modify the Primary Index Partition Ranges
The following ALTER TABLE request modifies the table created in “CREATE TABLE Request
for Examples 40- 47” on page 130. The request is valid if the table is empty.
ALTER TABLE orders
MODIFY PRIMARY INDEX
PARTITION BY RANGE_N(o_orderdate
BETWEEN DATE '1993-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH);
130
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 42: Drop and Add Primary Index Partition Ranges
The following ALTER TABLE request modifies the table created in “CREATE TABLE Request
for Examples 40- 47” on page 130. The outcome of this request is identical to the table
alterations performed in “Example 43: Drop and Add Primary Index Partition Ranges” on
page 131 and “Example 44: Drop and Add Primary Index Partition Ranges” on page 131 using
different syntax.
The request is valid if there are no rows with values for o_orderdate between January 1, 1992
(DATE ‘1992-01-01’) and December 31, 1992 (DATE ‘1992-12-31’).
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE BETWEEN DATE '1992-01-01'
AND
DATE '1992-12-31'
EACH INTERVAL ’1’ MONTH
ADD RANGE BETWEEN DATE '1999-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH;
Example 43: Drop and Add Primary Index Partition Ranges
The following ALTER TABLE request modifies the table created in “CREATE TABLE Request
for Examples 40- 47” on page 130. The result is equivalent to the outcome of the requests used
in “Example 42: Drop and Add Primary Index Partition Ranges” on page 131 and
“Example 44: Drop and Add Primary Index Partition Ranges” on page 131 using different
syntax and is valid if there are no rows with values for o_orderdate between January 1 1992
(DATE ‘1992-01-01’) and December 31 1992 (DATE ‘1992-12-31’).
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE WHERE PARTITION BETWEEN 1
AND
12
ADD RANGE BETWEEN DATE '1999-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH;
Example 44: Drop and Add Primary Index Partition Ranges
The following ALTER TABLE request modifies the table created in “CREATE TABLE Request
for Examples 40- 47” on page 130. The result is equivalent to the outcome of the requests used
in “Example 42: Drop and Add Primary Index Partition Ranges” on page 131 and
“Example 43: Drop and Add Primary Index Partition Ranges” on page 131 using different
syntax and is valid if there are no rows with values for o_orderdate between January 1 1992
(DATE ‘1992-01-01’) and December 31 1992 (DATE ‘1992-12-31’).
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE WHERE Orders.PARTITION IN (1,2,3,4,5,6,7,8,9,10,11,12)
ADD RANGE BETWEEN DATE '1999-01-01'
EACH INTERVAL '1' MONTH,
DATE '2000-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH;
SQL Reference: Data Definition Statements
131
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 45: Drop and Add Primary Index Partition Ranges and Delete
Rows Outside the Defined Ranges
The following ALTER TABLE request modifies the table created in “CREATE TABLE Request
for Examples 40- 47” on page 130. It is valid if there are 0 or more rows with o_orderdate
values between January 1 1992 (DATE ‘1992-01-01’) and December 31 1992 (DATE
‘1992-12-31’). As a result of the WITH DELETE specification, those rows, if any, are deleted
from orders because they do not belong to any partition in the new partitioning expression:
ALTER TABLE orders
MODIFY PRIMARY INDEX (o_orderkey)
DROP RANGE BETWEEN DATE ’1992-01-01’
AND
DATE ’1992-12-31’
EACH INTERVAL ’1’ MONTH
ADD RANGE BETWEEN DATE ’1999-01-01’
AND
DATE ’2000-12-31’
EACH INTERVAL ’1’ MONTH
WITH DELETE;
Example 46: Using MODIFY PRIMARY INDEX to Repartition a Table and
Save Nonvalid Rows That Result From the Redefinition in a Save Table
Assume that the orders table defined in “CREATE TABLE Request for Examples 40- 47” on
page 130 exists and the following new save table has been created to handle rows that are no
longer valid when you change the partitioning expression for the orders table:
CREATE TABLE old_orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
UNIQUE PRIMARY INDEX (o_orderkey);
The following ALTER TABLE request is valid if there are 0 or more rows with o_orderdate
between January 1, 1992 and December 31, 1992 (DATE '1992-01-01 AND
DATE '1992-12-31').
The rows having those values, if any, are moved into the old_orders save table and then deleted
from orders:
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE BETWEEN DATE ’1992-01-01’
AND
DATE ’1992-12-31’
EACH INTERVAL ’1’ MONTH
ADD RANGE BETWEEN DATE ’1999-01-01’
AND
DATE ’2000-12-31’
EACH INTERVAL ’1’ MONTH
WITH INSERT INTO old_orders;
132
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Example 47: Adding a Name to a Previously Unnamed Primary Index
To name the primary index of the orders table defined in “CREATE TABLE Request for
Examples 40- 47” on page 130, you could perform the following request:
ALTER TABLE orders
MODIFY PRIMARY INDEX ordpi;
Example 48: Revalidating the Partitioning for a PPI Table
Suppose any of the following events make you think that incorrect partitioning of the orders
table has occurred:
•
You suspect that row partitioning might not be correct after a restore.
•
You copy the table to a system with different hardware or operating system.
•
Some sort of system malfunction has occurred.
You can validate the partitioning of orders table rows using either of the following ALTER
TABLE requests, with the first request deleting any problematic rows and the second moving
them into a new table:
ALTER TABLE orders
REVALIDATE PRIMARY INDEX WITH DELETE;
ALTER TABLE orders
REVALIDATE PRIMARY INDEX WITH INSERT INTO old_orders;
Example 49: Unmatched Partitioning Expression Ranges
Assume that table cust_orderdate exists with the following definition:
CREATE TABLE cust_orderdate (
o_custkey
INTEGER,
o_orderdate DATE)
PRIMARY INDEX (o_custkey)
PARTITION BY RANGE_N(o_orderdate
BETWEEN DATE ’2000-01-01’
AND
DATE ’2000-12-31’
EACH INTERVAL ’1’ MONTH;
The following ALTER TABLE request returns an error because the expanded partitioning
expression ranges defined in the PARTITION BY clause of the CREATE TABLE request do not
match the expanded partitioning ranges defined by the ALTER TABLE specification.
ALTER TABLE cust_orderdate
MODIFY PRIMARY INDEX
DROP RANGE BETWEEN DATE ’2000-01-01’
AND
DATE ’2000-04-30’;
The current table, after expansion of the EACH clause, has 12 ranges, each with a width of one
month. The DROP RANGE clause of this ALTER TABLE request, as written, attempts to drop
a single range with a width of four months, and that range does not match any of the ranges
currently defined for cust_orderdate.
SQL Reference: Data Definition Statements
133
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
The following two ALTER TABLE requests produce the result intended by the nonvalid
ALTER TABLE request in “Example 49: Unmatched Partitioning Expression Ranges” on
page 133, each using a different syntax:
ALTER TABLE cust_orderdate
MODIFY PRIMARY INDEX
DROP RANGE BETWEEN DATE ’2000-01-01’
AND
DATE ’2000-04-30’
EACH INTERVAL ’1’ MONTH;
ALTER TABLE cust_orderdate
MODIFY PRIMARY INDEX
DROP RANGE WHERE PARTITION <=4;
Example 50: Dropping a Partition From a PPI Table When the PPI Is
Defined Using The RANGE_N Function and NO RANGE Is Specified
Suppose you have the following PPI base table definition:
CREATE SET TABLE ppi_salestable, NO FALLBACK,
NO BEFORE JOURNAL, NO AFTER JOURNAL, CHECKSUM = DEFAULT (
product_code CHARACTER(8) CHARACTER SET LATIN NOT CASESPECIFIC,
sales_date
DATE FORMAT 'YYYY-MM-DD',
agent_id
CHARACTER(8) CHARACTER SET LATIN NOT CASESPECIFIC,
quantity_sold INTEGER,
product_desc VARCHAR(50) CHARACTER SET LATIN NOT CASESPECIFIC)
PRIMARY INDEX (product_code, sales_date, agent_id)
PARTITION BY RANGE_N(sales_date
BETWEEN DATE '2001-01-01'
AND
DATE '2001-12-31'
EACH INTERVAL '1' MONTH ,
'2002-01-01'(DATE)
AND
'2002-12-31'(DATE)
EACH INTERVAL '1' MONTH ,
'2003-01-01'(DATE)
AND
'2003-12-31'(DATE)
EACH INTERVAL '1' MONTH ,
NO RANGE);
You then define the following PPI base table to act as the save table for an ALTER TABLE
request in which you will drop one or more partitions from ppi_salestable:
CREATE SET TABLE ppi_salestable1, NO FALLBACK,
NO BEFORE JOURNAL, NO AFTER JOURNAL, CHECKSUM = DEFAULT (
product_code CHARACTER(8) CHARACTER SET LATIN NOT CASESPECIFIC,
sales_date
DATE FORMAT 'YYYY-MM-DD',
agent_id
CHARACTER(8) CHARACTER SET LATIN NOT CASESPECIFIC,
quantity_sold INTEGER,
product_desc VARCHAR(50) CHARACTER SET LATIN NOT CASESPECIFIC)
PRIMARY INDEX (product_code, sales_date, agent_id)
PARTITION BY RANGE_N(sales_date
BETWEEN DATE '2001-01-01'
AND
DATE '2001-12-31'
EACH INTERVAL '1' MONTH , NO RANGE);
134
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
You then populate ppi_salestable with the following rows:
INSERT INTO ppi_salestable
VALUES ('PC2','2001-01-10','AG2',5,'PC');
INSERT INTO ppi_salestable
VALUES ('PC3','2001-03-10','AG2',5,'PC');
INSERT INTO ppi_salestable
VALUES ('PC4','2002-05-10','AG2',5,'PC');
INSERT INTO ppi_salestable
VALUES ('PC5','2003-07-10','AG2',5,'PC');
INSERT INTO ppi_salestable
VALUES ('PC5','2004-07-10','AG2',5,'PC');
The following SELECT request indicates that the five intended rows were successfully inserted
into ppi_salestable:
SELECT partition, product_code, sales_date, agent_id,
quantity_sold, product_description
FROM ppi_salestable
ORDER BY 1;
PARTITION
--------1
3
17
31
37
product_code
-----------PC2
PC3
PC4
PC5
PC5
sales_date
---------2001-01-10
2001-03-10
2002-05-10
2003-07-10
2004-07-10
agent_id quantity_sold product_desc
-------- ------------- -----------AG2
5 PC
AG2
5 PC
AG2
5 PC
AG2
5 PC
AG2
5 PC
You now use ALTER TABLE to drop a range of partitions from ppi_salestable with the intent of
saving any dropped rows in ppi_salestable1, specifying a WITH INSERT INTO
ppi_salestable1 clause to do so:
ALTER TABLE ppi_salestable
MODIFY PRIMARY INDEX (product_code, sales_date, agent_id)
DROP RANGE BETWEEN DATE '2001-01-01'
AND
DATE '2001-12-31'
EACH INTERVAL '1' MONTH
WITH INSERT INTO ppi_salestable1;
*** Table has been modified.
*** Total elapsed time was 1 second.
Now you check the contents of ppi_salestable to ensure that the rows within the partition you
dropped were removed from the table:
SELECT PARTITION, product_code, sales_date, agent_id,
quantity_sold, product_desc
FROM ppi_salestable
ORDER BY 1;
*** Query completed. 5 rows found. 6 columns returned.
*** Total elapsed time was 1 second.
SQL Reference: Data Definition Statements
135
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
PARTITION
--------5
19
25
25
25
product_code
-----------PC4
PC5
PC2
PC3
PC5
sales_date
---------2002-05-10
2003-07-10
2001-01-10
2001-03-10
2004-07-10
agent_id quantity_sold product_desc
-------- ------------- -----------AG2
5 PC
AG2
5 PC
AG2
5 PC<<<<<
AG2
5 PC<<<<<
AG2
5 PC<<<<<
Notice that because you specified a NO RANGE clause when you created the base table
ppi_salestable, no rows are dropped from it when you drop the range of partitions that had
contained them. Instead, those rows are moved to the NO RANGE partition, which is
identified by the external partition number 25, and retained in ppi_salestable.
To do what you had intended, you should have defined ppi_salestable without specifying a NO
RANGE clause.
Example 51: Altering Partitions for Multilevel PPI Tables
Assume you have created a table named orders using the following CREATE TABLE request:
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus CHARACTER(1) CASESPECIFIC,
o_totalprice DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL)
PRIMARY INDEX (o_orderkey)
PARTITION BY (
RANGE_N(o_custkey
BETWEEN 0
AND 49999
EACH 100),
RANGE_N(o_orderdate BETWEEN DATE '2000-01-01'
AND DATE
'2006-12-31'
EACH INTERVAL '1' MONTH))
UNIQUE INDEX (o_orderkey);
If orders is empty, you could submit the following ALTER TABLE request to modify it to have
a single-level partitioned primary index:
ALTER TABLE orders
MODIFY PRIMARY INDEX
PARTITION BY RANGE_N(
o_orderdate BETWEEN DATE '2000-01-01'
AND
DATE '2006-12-31'
EACH INTERVAL '1' MONTH);
Assume the previously defined CREATE TABLE definition for orders. If there are no rows with
o_orderdate between the dates 2000-01-01 and 2000-12-31, you could submit any one of the
following equivalent ALTER TABLE requests to modify the partitioning expression for level 2:
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE #L2 BETWEEN DATE '2000-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH
ADD RANGE
BETWEEN DATE '2007-01-01'
AND
DATE '2007-12-31'
EACH INTERVAL '1' MONTH;
136
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
or
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE #L2
WHERE Orders.PARTITION#L2 BETWEEN 1
AND
12
ADD RANGE #L2
BETWEEN DATE '2007-01-01'
AND
DATE '2007-12-31'
EACH INTERVAL '1' MONTH;
or
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE #L2
WHERE PARTITION#L2 IN (1,2,3,4,5,6,7,8,9,10,11,12)
ADD RANGE BETWEEN DATE '2007-01-01'
EACH INTERVAL '1' MONTH,
DATE '2007-07-01'
AND
DATE '2007-12-31'
EACH INTERVAL '1' MONTH;
Assume the previously defined CREATE TABLE definition for orders. If there are zero, one, or
more rows with o_orderdate between 2000-01-01 and 2000-12-31, you could submit the
following ALTER TABLE request to alter the partitioning. In this case, the system deletes the
rows satisfying the condition:
ALTER TABLE orders
MODIFY PRIMARY INDEX (o_orderkey)
DROP RANGE #L2 BETWEEN DATE '2000-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH
ADD RANGE
BETWEEN DATE '2007-01-01'
AND
DATE '2007-12-31'
EACH INTERVAL '1' MONTH
WITH DELETE;
Assume you have created one table using the previously defined CREATE TABLE definition
for orders and another table using the following CREATE TABLE request:
CREATE TABLE old_orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus CHARACTER(1) CASESPECIFIC,
o_totalprice DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL)
UNIQUE PRIMARY INDEX (o_orderkey);
SQL Reference: Data Definition Statements
137
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
The following ALTER TABLE request is one way to alter the partitioning if there are zero, one,
or more rows with o_orderdate between 2000-01-01 and 2000-12-31. In this case, the system
saves the rows in old_orders prior to deleting them from orders.
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE #L2 BETWEEN DATE '2000-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH
ADD RANGE #L2 BETWEEN DATE '2007-01-01'
AND
DATE '2007-12-31'
EACH INTERVAL '1' MONTH
WITH INSERT INTO old_orders;
The following ALTER TABLE request is not valid for a nonempty table because it changes the
number of partitions at a level other than level 1:
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE #L2 BETWEEN DATE '2000-01-01'
AND
DATE '2000-12-31'
EACH INTERVAL '1' MONTH
ADD RANGE
BETWEEN DATE '2007-01-01'
AND
DATE '2008-12-31'
EACH INTERVAL '1' MONTH
WITH DELETE;
Assume the previously defined CREATE TABLE definition for orders. You could submit the
following ALTER TABLE request to alter the partitioning expressions at both levels:
ALTER TABLE orders
MODIFY PRIMARY INDEX
DROP RANGE BETWEEN
0
BETWEEN
99
ADD RANGE BETWEEN 50000
AND
50199
EACH 100,
DROP RANGE WHERE PARTITION#L2 = 1
ADD RANGE BETWEEN DATE '2007-01-01'
AND
DATE '2007-01-31'
WITH DELETE;
Note that the number of partitions at level 1 is increased by one and the number of partitions
at level 2 remains the same.
Example 52: Adding a LOB Column to a Table
The following example adds the CLOB column extended_description to a table named
partshistory:
ALTER TABLE partshistory
ADD extended_description CLOB;
138
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TABLE
Related Topics
See “CREATE TABLE” on page 648 and “CREATE TABLE (Queue Table Form)” on page 817
for further information about table definitions and primary index partitioning.
See Database Design for more information about partitioned primary indexes and the
system-derived PARTITION and PARTITION#Ln columns.
See SQL Reference: Statement and Transaction Processing for information about the various
forms of partition elimination.
SQL Reference: Data Definition Statements
139
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TRIGGER
ALTER TRIGGER
Purpose
Enables or disables a trigger or changes its creation timestamp.
Syntax
ALTER TRIGGER
database_name.
trigger_name
ENABLED
table_name
trigger_name
TIMESTAMP
DISABLED
;
1101A201
where:
Syntax Element …
Specifies …
database_name
an optional qualifier for the trigger_name or table_name.
trigger_name
the name of the trigger to be altered.
If you specify trigger_name you can alter only one trigger at a time.
table_name
the name of the table, all the triggers on which are to be enabled or disabled.
The TIMESTAMP option does not apply to a table.
ENABLED
that the named trigger or all triggers on the named table are to be enabled.
Enabled triggers function as active database objects and follow normal trigger
protocol.
DISABLED
that the named trigger or all triggers on the named table are to be disabled.
Disabled triggers continue to exist as database objects, but cannot execute. For
a trigger to execute, it must first be enabled.
TIMESTAMP
that the creation timestamp of the named trigger is to be replaced with the
current timestamp.
Altering the creation timestamp of a trigger changes its position in the default
order of execution, when multiple triggers are defined on a table.
ANSI Compliance
ALTER TRIGGER is a Teradata extension to the ANSI SQL:2003 standard.
Authorization
To perform ALTER TRIGGER, you must have the DROP TRIGGER privilege on the table on
which the trigger is defined, or on the database containing it.
140
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TRIGGER
Privileges Granted Automatically
None.
The Purpose of ALTER TRIGGER Options
The ALTER TRIGGER... DISABLED function is very useful in temporarily disabling or
enabling triggers without dropping the triggers created for some purpose.
Utilities such as FastLoad and MultiLoad cannot operate on tables having enabled triggers
defined on them. Disabling the triggers enables bulk loading of data into such tables.
The Teradata Parallel Data Pump utility operates even on tables with enabled triggers, but
there can be some negative performance issues that arise if you do this.
Some triggers are created to coordinate actions on a set of tables. If such triggers are disabled
for some period of time, the application must ensure that the relationship among the set of
tables and the trigger is not lost.
The TIMESTAMP option is useful to change the order of execution of triggers, particularly
those triggers that were created without the ORDER clause. If you do not specify a
TIMESTAMP, then the existing timestamp for the trigger is not changed.
ALTER TRIGGER uses the current time when adding a timestamp, so when you want to
change the timings for multiple order-sensitive triggers defined on the same table, you must
submit ALTER TRIGGER statements that change their timestamps in the required order to
ensure the correct execution precedence.
Altering All Triggers on a Table
If you enter a table name instead of a trigger name, then ALTER TRIGGER enables or disables
all the triggers defined on that table.
If some of the triggers on a table are in disabled state and some are enabled the effect of the
ALTER TRIGGER command specified for a table name is as follows:
IF you specify this option …
THEN the effect is all the triggers defined on the named table that are in
an …
ENABLED
disabled state are enabled.
The command has no effect on enabled triggers.
DISABLED
enabled state are disabled.
The command has no effect on disabled triggers.
Related Topics
See “CREATE TRIGGER/ REPLACE TRIGGER” on page 870 for more information about
trigger definitions.
SQL Reference: Data Definition Statements
141
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
ALTER TYPE
Purpose
Performs any of the following operations:
•
Add a new attribute to a structured UDT definition.
•
Drop an existing attribute from a structured UDT definition.
•
Add a method to a distinct or structured UDT definition.
•
Drop a method from a distinct or structured UDT definition.
Syntax
,
UDT_name
ALTER TYPE
ADD
attribute_name
ATTRIBUTE
data_type
SYSUDTLIB.
UDT_name
;
SYSUDTLIB.
,
DROP
ATTRIBUTE
attribute_name
data_type
UDT_name
SYSUDTLIB.
ADD
method_name
METHOD
data_type
(
CONSTRUCTOR
data_type
RETURNS
,
SYSUDTLIB.
INSTANCE
UDT_name
(
SYSUDTLIB.
UDT_name
LANGUAGE
SYSUDTLIB.
C
CPP
PARAMETER STYLE
SQL
TD_GENERAL
DETERMINISTIC
NOT
NO SQL
specific_method_name
SPECIFIC METHOD
data_type
(
UDT_name
FOR
,
SYSUDTLIB.
SYSUDTLIB.
(
UDT_name
SYSUDTLIB.
DROP
method_name
METHOD
INSTANCE
SYSUDTLIB.
RETURNS
,
(
data_type
CONSTRUCTOR
data_type
UDT_name
(
SYSUDTLIB.
UDT_name
LANGUAGE
SYSUDTLIB.
C
CPP
PARAMETER STYLE
SQL
TD_GENERAL
DETERMINISTIC
NOT
NO SQL
specific_method_name
SPECIFIC METHOD
SYSUDTLIB.
UDT_name
FOR
,
data_type
(
(
SYSUDTLIB.
UDT_name
SYSUDTLIB.
COMPILE
ONLY
142
1101B368
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
where:
Syntax element …
Specifies …
[SYSUDTLIB.] UDT_name
the name of the UDT whose definition is to be altered.
ADD ATTRIBUTE attribute_name
to add the attribute named attribute_name to the definition
of the structured UDT named UDT_name.
You cannot add more than 512 attributes at a time.
data_type | [SYSUDTLIB.]
UDT_name
the data type of the attribute to be added.
DROP ATTRIBUTE attribute_name
to drop the attribute named attribute_name from the
definition of the structured UDT named UDT_name.
ADD [INSTANCE |
CONSTRUCTOR] METHOD
[SYSUDTLIB.] method_name
to add the method signature for the method named
method_name to the definition of the UDT named
UDT_name.
You must use the CREATE METHOD statement (see
“CREATE METHOD” on page 431) to create the body for
method_name before you can invoke it.
data_type | SYSUDTLIB.]
UDT_name
the data type list for the method to be added.
RETURNS data_type |
[SYSUDTLIB.] UDT_name
the list of the data types returned by method_name.
LANGUAGE
the code for the language in which the external routine for
method_name is written.
Code
Language
C
C
CPP
C++
See “Language Clause” on page 250 for details.
PARAMETER STYLE
the parameter passing style for method_name.
Parameter Style
SQL
Description
allows the code body to indicate
NULL data.
This is the default parameter style.
TD_GENERAL
the code body cannot indicate
NULL data.
See “Parameter Style Clause” on page 253 for details.
SQL Reference: Data Definition Statements
143
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Syntax element …
Specifies …
[NOT] DETERMINISTIC
whether method_name returns the same results for identical
inputs or not. The clause is documentary only.
See “Deterministic Characteristics Clause” on page 254 for
details.
NO SQL
whether SQL language calls are permitted within the
user-written external routine for method_name.
The only valid specification is NO SQL.
See “SQL Data Access Clause” on page 251 for details.
ADD SPECIFIC METHOD
[SYSUDTLIB.]
specific_method_name
to add the specific method named specific_method_name to
the definition of the UDT named UDT_name.
data_type | SUSUDTLIB.]
UDT_name
the data type list for the specific_method_name.
RETURNS data_type |
[SYSUDTLIB.] UDT_name
the list of the data types returned by method_name.
LANGUAGE
the code for the language in which the external routine for
method_name is written.
See “Language Clause” on page 250 for details.
PARAMETER STYLE
the parameter passing style for method_name.
See “Parameter Style Clause” on page 253 for details.
[NOT] DETERMINISTIC
whether method_name returns the same results for identical
inputs or not. The clause is documentary only.
See “Deterministic Characteristics Clause” on page 254 for
details.
NO SQL
The SQL language call specification for the user-written
external routine for method_name.
The only valid specification is NO SQL.
See “SQL Data Access Clause” on page 251 for details.
DROP [INSTANCE |
CONSTRUCTOR] METHOD
[SYSUDTLIB.] method_name
to drop the instance or constructor method named
method_name from the definition of the UDT named
UDT_name.
You cannot drop observer or mutator methods.
To replace the external routine for a method, use the
REPLACE METHOD statement (see “REPLACE METHOD”
on page 1112).
INSTANCE is the default.
data_type | UDT_name
144
the data type of the attribute to be dropped.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Syntax element …
Specifies …
DROP SPECIFIC METHOD
[SYSUDTLIB.]
specific_method_name
to drop the specific method named specific_method_name
from the definition of the UDT named in the FOR
UDT_name clause.
When you drop a method definition, the system also destroys
all files associated with that method.
To replace the external routine for a method, use the
REPLACE METHOD statement (see “REPLACE METHOD”
on page 1112).
data_type | UDT_name
the data type of the attribute to be dropped.
FOR UDT_name
the name of the UDT from which the association with the
specified set of method signatures is to be dropped.
COMPILE
to do all of the following things:
•
•
•
•
Recompile the code source for the specified type.
Generate the object code.
Recreate the appropriate.so or .dll file.
Distribute the recreated .so or .dll file to all nodes of the
system.
The system replaces the existing type with the recompiled
version.
Note that you must recompile all UDTs when you upgrade or
migrate to Teradata Database 12.0.
COMPILE ONLY
to do both of the following things:
• Recompile the code source for the specified type.
• Generate the object code.
If you specify COMPILE ONLY, the system does not generate
or distribute the .so or .dll file.
The system does replace the existing type with the
recompiled version.
Note that you must recompile all UDTs when you upgrade or
migrate to Teradata Database 12.0.
ANSI Compliance
ALTER TYPE is ANSI SQL-2003-compliant with Teradata extensions.
Authorization
To add or drop an attribute, you must have the UDTTYPE or UDTMETHOD privilege on the
SYSUDTLIB database.
To add or drop a method, you must have the UDTMETHOD privilege on the SYSUDTLIB
database.
SQL Reference: Data Definition Statements
145
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Privileges Granted Automatically
None.
Adding Attributes To a Structured UDT
The system automatically generates an associated observer and mutator method for each
attribute you add to a UDT.
The following rules apply to adding attributes:
•
The UDT that you specify must be a structured UDT.
•
The specified UDT must not be referenced by any other database object.
•
An attempt to add an attribute to a UDT being referenced by some other database object,
such as being used as the column data type of any table, aborts the request and returns an
error to the requestor.
To be explicit, any of the following conditions cause the request to abort:
•
There is a table in any database for which the data type of one of the columns is the
specified UDT.
•
There is a structured UDT for which the data type of one of the attributes is the
specified UDT.
•
The specified UDT is referenced in a user-defined cast (see “CREATE CAST/
REPLACE CAST” on page 184).
•
There is a method or UDF in any database that references the specified UDT.
•
There is an ordering or transform group defined for the UDT (see “CREATE
ORDERING/ REPLACE ORDERING” on page 455 and “CREATE TRANSFORM/
REPLACE TRANSFORM” on page 855).
•
The name of an added attribute must be different than all existing attribute names for the
specified UDT.
•
The system creates a default observer and mutator method for each new attribute that you
add.
The method signatures of the observer and mutator must be different than all existing
method signatures for the specified UDT.
This means that you, as a UDT developer, must perform all the necessary cleanup on all of the
following database objects before you add any attributes to a structured UDT:
•
Casts associated with the UDT.
See “CREATE CAST/ REPLACE CAST” on page 184.
•
Orderings for the UDT.
See “CREATE ORDERING/ REPLACE ORDERING” on page 455.
•
Transforms for the UDT.
See “CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855.
•
Tables whose columns are typed with the UDT.
See “CREATE TABLE” on page 648.
146
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
•
Structured UDTs that use the UDT.
See “CREATE TYPE (Structured Form)” on page 927.
•
UDFs and UDMs that use the UDT as a parameter type.
See “CREATE FUNCTION/ REPLACE FUNCTION” on page 222 and “CREATE
METHOD” on page 431.
You must also remove any dependent objects before you add attributes to a structured type. To
assist you in this task, you can use a system-installed macro found in the SYSUDTLIB database
that lists all dependencies and the order in which they must be dropped.
To do this, type the following statement:
SYSUDTLIB.HelpDependencies(‘UDT_name’);
where UDT_name is the name of the structured UDT to which you are adding an attribute set.
The ability to add multiple attributes using the ADD ATTRIBUTE option is a Teradata
extension to the ANSI SQL:2003 standard. You have the option of either submitting ALTER
TYPE statements that comply with the ANSI SQL standard by adding only one attribute at a
time, or of adding multiple attributes simultaneously using the Teradata extension to the
ANSI SQL:2003 syntax.
You cannot add more than 512 attributes at a time to a structured UDT.
Workaround for Adding More Than 512 Attributes to a Structured UDT
The number of attributes that can be added to a structured UDT per ALTER TYPE … ADD
ATTRIBUTE request varies between 300 and 512, depending on the platform. The limit is
imposed because of restrictions on the availability of the Parser memory that is required to
register the auto-generated observer and mutator methods for a structured type, not because
of the limit on the total number of attributes that can be defined per structured type, which is
roughly 4,000.
The workaround for this is just to submit as many individual ALTER TYPE … ADD
ATTRIBUTE requests, each having an upper limit of 512 attributes, as required to define the
desired total number of attributes for the structured UDT.
Dropping Attributes From a Structured UDT
The system automatically removes the associated observer and mutator methods for each
attribute that you drop.
The following rules apply to dropping attributes:
•
The specified UDT must be a structured type.
•
The specified UDT must not be referenced by any other database object.
An attempt to drop an attribute from a UDT being referenced by some other database
object, such as being used as the column data type of any table, aborts the request and
returns an error to the requestor.
SQL Reference: Data Definition Statements
147
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
To be explicit, any of the following conditions cause the request to abort:
•
•
There is a table in any database for which the data type of one of the columns is the
specified UDT.
•
There is a structured UDT for which the data type of one of the attributes is the
specified UDT.
•
The specified UDT is referenced in a user-defined cast (see “CREATE CAST/
REPLACE CAST” on page 184).
•
There is a method or UDF in any database that references the specified UDT.
•
There is an ordering or transform group defined for the UDT (see “CREATE
ORDERING/ REPLACE ORDERING” on page 455 and “CREATE TRANSFORM/
REPLACE TRANSFORM” on page 855).
The attribute to be dropped must not be the only attribute of the UDT.
You, as a UDT developer, are responsible for performing all the necessary cleanup on all of the
following database objects before you drop any attributes from a structured UDT:
•
Casts associated with the UDT.
See “CREATE CAST/ REPLACE CAST” on page 184.
•
Orderings for the UDT.
See “CREATE ORDERING/ REPLACE ORDERING” on page 455.
•
Transforms for the UDT.
See “CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855.
•
Tables whose columns are typed with the UDT.
See “CREATE TABLE” on page 648.
•
Structured UDTs that use the UDT.
See “CREATE TYPE (Structured Form)” on page 927.
•
UDFs and UDMs that use the UDT as a parameter type.
See “CREATE FUNCTION/ REPLACE FUNCTION” on page 222 and “CREATE
METHOD” on page 431.
You can drop attributes from a structured UDT definition even if any of the following
database objects references the observer or mutator methods associated with that attribute:
•
Cast
•
Macro
•
Stored Procedure
•
Trigger
•
View
However, when you attempt to execute any of the affected database objects, the request aborts
and an error is returned to the requestor.
148
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Adding Methods To a UDT
This clause adds a method signature to the specified UDT. You cannot invoke the new method
until its body is specified completely with an appropriate CREATE METHOD statement (see
“CREATE METHOD” on page 431).
A new method cannot be a duplicate of any existing methods associated with the specified
UDT.
IF the UDT is this type …
THEN the new method associated with it must be specified as a …
distinct
distinct type method.
structured
structured type method.
The ability to add multiple methods using the ADD METHOD option is a Teradata extension
to the ANSI SQL:2003 standard. You have the option of either submitting ALTER TYPE
statements that comply with the ANSI SQL standard by adding only one method at a time, or
of adding multiple methods simultaneously using the Teradata extension to the ANSI
SQL:2003 syntax.
Dropping Methods From a UDT
This clause is used to drop a method signature associated with the specified UDT from the
definition of that UDT. This is the only way you can drop a method. There is no DROP
METHOD statement.
If you do not specify a method type, the default type is INSTANCE.
You cannot drop observer or mutator methods from a UDT definition.
When you drop a method signature from a UDT definition, the system also destroys its
associated external routines.
The method to be dropped must not be referenced by any of the following database
definitions:
•
A cast.
See “CREATE CAST/ REPLACE CAST” on page 184.
•
An ordering.
See “CREATE ORDERING/ REPLACE ORDERING” on page 455.
•
A transform set.
See “CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855.
SQL Reference: Data Definition Statements
149
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
You can drop methods from a UDT definition even if any of the following database objects
references it:
•
Cast
•
Macro
•
Stored Procedure
•
Trigger
•
View
However, when you attempt to execute any of the affected database objects, the request aborts
and an error is returned to the requestor.
The ANSI SQL standard does not permit you to drop methods from a distinct UDT
definition; however, you can drop methods from distinct UDTs as a Teradata extension to the
ANSI SQL:2003 standard.
To replace the external routine for a method, use the REPLACE METHOD statement (see
“REPLACE METHOD” on page 1112).
Altering Attributes Of A Structured UDT Definition
If you attempt to add or drop an attribute from the specified structured UDT, the system
aborts the request if any other database object references the that UDT.
This action protects the integrity of the database from corruption caused by objects
depending on the previous definition of a structured UDT that is no longer correct.
You, as a UDT developer, are responsible for performing all the necessary clean up on all of
the following database objects before you drop any attributes from a structured UDT:
•
Casts associated with the UDT.
See “CREATE CAST/ REPLACE CAST” on page 184.
•
Orderings for the UDT.
See “CREATE ORDERING/ REPLACE ORDERING” on page 455.
•
Transforms for the UDT.
See “CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855.
•
Tables whose columns are typed with the UDT.
See “CREATE TABLE” on page 648.
•
Structured UDTs that use the UDT.
See “CREATE TYPE (Structured Form)” on page 927.
•
UDFs and UDMs that use the UDT as a parameter type.
See “CREATE FUNCTION/ REPLACE FUNCTION” on page 222 and “CREATE
METHOD” on page 431.
150
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Altering The Method Signatures Of A Structured UDT Definition
If you attempt to add or drop a method signature from the specified UDT, the system aborts
the request if any cast, ordering, or transform set definition in the system references the
method (see “CREATE CAST/ REPLACE CAST” on page 184, “CREATE ORDERING/
REPLACE ORDERING” on page 455, and “CREATE TRANSFORM/ REPLACE
TRANSFORM” on page 855).
This action protects the integrity of the database from corruption caused by objects
depending on the previous definition of a structured UDT that is no longer correct.
Recompiling a UDT
It might become necessary to recompile one or all of your UDTs. An example might be an
upgrade or migration to a newer release. For example, you must recompile all UDTs when you
upgrade or migrate to Teradata Database 12.0.33
Recompiling a UDT is a simple operation. All you must do is submit an ALTER TYPE request
that does the following:
•
Specifies the name of the UDT to be recompiled.
•
Specifies the COMPILE option.
A successful ALTER TYPE … COMPILE request does the following things:
•
Recompiles the code source for the specified type.
•
Generates the new object code.
•
Recreates the appropriate .so or .dll file.
•
Distributes the recreated .so or .dll file to all nodes of the system.
Example 1: COMPILE Option
The following example recompiles the UDT named address, generates the appropriate object
code, generates the new .so or .dll library, and redistributes it to all system nodes:
ALTER TYPE address COMPILE;
Example 2: COMPILE ONLY Option
The following example recompiles the UDT named address and generates the appropriate
object code, but does not generate the new .so or .dll library, or redistribute it to all system
nodes:
ALTER TYPE address COMPILE ONLY;
33. Note that the upgrade process undertaken by the Parallel Upgrade Tool (PUT) and the migration process
undertaken by the Archive/Restore utility both automatically recompile all UDTs defined for your system.
SQL Reference: Data Definition Statements
151
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Example 3
The following example adds an attribute named country to the structured UDT named
address:
ALTER TYPE address
/* Add attribute to structured type */
ADD ATTRIBUTE country VARCHAR(15);
Example 4
The following example adds three attributes named country, continent, and zone to the
structured UDT named address:
ALTER TYPE address
/* Add 3 attributes to structured type */
ADD ATTRIBUTE country
VARCHAR(15),
continent VARCHAR(20),
zone
INTEGER;
Example 5
The following example adds two instance methods named toYen() and toPeso() to the
structured UDT named euro:
ALTER TYPE euro
/* Add 2 original methods */
ADD INSTANCE METHOD
toYen()
RETURNS yen
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NO SQL,
toPeso()
RETURNS peso
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NO SQL;
Example 6
The following example adds a new instance method named toYen() to the structured UDT
named euro:
ALTER TYPE euro
/* Add original method */
ADD INSTANCE METHOD toYen()
RETURNS yen
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NO SQL;
152
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
Example 7
The following example drops the attribute named country from the structured UDT named
address:
ALTER TYPE address
/* Drop attribute of structured type */
DROP ATTRIBUTE country;
Example 8
The following example drops the method having the specific method name polygon_mbr from
the structured UDT named polygon:
ALTER TYPE polygon
/* Drop method */
DROP SPECIFIC METHOD SYSUDTLIB.polygon_mbr;
Related Topics
The following topics and manual provide additional information about user-defined data
types:
•
“ALTER METHOD” on page 28
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE CAST/ REPLACE CAST” on page 184
•
“CREATE METHOD” on page 431
•
“CREATE ORDERING/ REPLACE ORDERING” on page 455
•
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855
•
“CREATE TYPE (Structured Form)” on page 927
•
“DROP AUTHORIZATION” on page 1001
•
“DROP CAST” on page 1003
•
“DROP ORDERING” on page 1032
•
“DROP TRANSFORM” on page 1041
•
“DROP TYPE” on page 1043
•
“HELP CAST” on page 1427
•
“HELP FUNCTION” on page 1464
•
“HELP METHOD” on page 1493
•
“HELP TRANSFORM” on page 1557
•
“HELP TYPE” on page 1563
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
SQL Reference: Data Definition Statements
153
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
ALTER TYPE
See Chapter 5: “SQL DCL Syntax,” for information about the UDTTYPE, UDTMETHOD,
UDTUSAGE, and EXECUTE FUNCTION privileges, particularly as described for the
“GRANT (SQL Form)” on page 1199, and the topics “EXECUTE FUNCTION Privilege” on
page 1224 and “UDT-Related Privileges” on page 1225.
Also see SQL Reference: UDF, UDM, and External Stored Procedure Programming for
information about how to write user-defined external routines.
154
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
BEGIN LOGGING
Purpose
Starts the auditing of SQL requests that attempt to access data.
Also see “END LOGGING” on page 1049.
Syntax
ON
BEGIN LOGGING
DENIALS
A
WITH TEXT
FIRST
LAST
FIRST AND LAST
EACH
ALL
,
A
operation
GRANT
,
BY
database_name
user_name
ON
AUTHORIZATION
authorization_name
;
DATABASE database_name
USER user_name
object_name
TABLE
VIEW
database_name .
MACRO
PROCEDURE
FUNCTION
TYPE
1101V044
where:
Syntax Element …
Specifies …
DENIALS
that entries should be made only when statement execution fails because the user
did not have the privilege(s) necessary to perform the statement.
DENIALS is applied to only those actions listed in the BEGIN LOGGING
statement that contains it.
For example, two BEGIN LOGGING statements can specify the same object, user,
and action, but different frequency and DENIALS options. This allows the user to
log all denials, but only the first successful use of a privilege.
If this option is not specified, a log entry is made if the privilege check either fails
or succeeds.
SQL Reference: Data Definition Statements
155
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Syntax Element …
Specifies …
WITH TEXT
that the text of the statement which caused the log entry is to be saved in the log.
If two BEGIN LOGGING statements specify the same user, object, and action, and
one of the statements specifies the DENIALS option, then WITH TEXT can be
specified on either one of the statements, on both statements, or on neither
statement.
FIRST
LAST
FIRST AND LAST
EACH
IF WITH TEXT is specified …
THEN the text is …
only on the statement that also specifies
DENIALS
saved only when the entry is created
as a result of a denial.
either without DENIALS or on both
statements
always saved.
on END LOGGING
not saved for the specified actions or
the DENIALS specification, but the
logging frequency is not affected.
the frequency with which to log events.
The default is FIRST.
The only valid combination is FIRST AND LAST.
A log entry is made for either the first, the last, the first and last, or each time
during any session that the specified action is attempted against the specified
object.
If logging is already begun for an action on an object, a subsequent statement to
begin logging for the same object, action, user, and DENIALS specification causes
only the current frequency of logging to be changed to whatever the new
statement specifies.
ALL
operation
GRANT
the events to record in log entries.
ALL specifies that a log entry is potentially to be made when any of the actions in
the following list is attempted against the specified object.
Note that both the name and ID for each column are logged when you log
privileges to UPDATE and REFERENCES.
If logging has begun for ALL actions on an object, a statement to begin or end
logging for an action will change logging activity only for the specified action.
156
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Syntax Element …
Specifies …
ALL
operation
GRANT
One or more action names from the following list can be used to specify the type
of access to be logged. These are the same names as those for the statements for
which an access privilege can be granted.
(continued)
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
ALTER EXTERNAL PROCEDURE
ALTER FUNCTION
ALTER REPLICATION GROUP
CHECKPOINT
CREATE AUTHORIZATION
CREATE DATABASE
CREATE EXTERNAL PROCEDURE
CREATE FUNCTION
CREATE MACRO
CREATE PROCEDURE
CREATE PROFILE
CREATE REPLICATION GROUP
CREATE ROLE
CREATE TABLE
CREATE TRIGGER
CREATE USER
CREATE VIEW
DELETE
DROP AUTHORIZATION
DROP DATABASE
DROP FUNCTION
DROP MACRO
DROP PROCEDURE
DROP PROFILE
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
DROP REPLICATION GROUP
DROP ROLE
DROP TABLE
DROP TRIGGER
DROP USER
DROP VIEW
DUMP
EXECUTE
EXECUTE FUNCTION
EXECUTE PROCEDURE
GRANT
INDEX
INSERT
REFERENCES
RESTORE
ROLLBACK DATABASE
ROLLFORWARD DATABASE
SELECT
SET SESSION OVERRIDE
REPLICATION
UDTMETHOD
UDTTYPE
UDTUSAGE
UPDATE
The ALL option does not include logging of the following actions because they do
not apply to a specific object:
•
•
•
•
BY database_name
ALTER REPLICATION GROUP
CREATE PROFILE
CREATE REPLICATION GROUP
CREATE ROLE
•
•
•
•
DROP PROFILE
DROP REPLICATION GROUP
DROP PROFILE
SET SESSION OVERRIDE
REPLICATION
the community for which log entries should be made.
If you specify user_name, then it must be a user currently defined to the system.
Absence of the BY user_name option specifies all users (those already defined to
the system as well as any defined in the future while this logging directive is in
effect).
If neither BY user_name nor ON keyword object_name are specified, then the
specified action is logged for all users and objects throughout the system.
SQL Reference: Data Definition Statements
157
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Syntax Element …
Specifies …
ON
one or more entities for which log entries are to be made.
Absence of the ON keyword object_name option specifies logging of all entities the
user attempts to access.
If neither ON keyword object_name nor BY user_name is specified, then the
specified action is logged for all users and objects throughout the system.
The ON keyword object_name option does not apply to the CREATE PROFILE,
DROP PROFILE, CREATE ROLE, or DROP ROLE action.
the name of the object to be logged.
AUTHORIZATION
authorization_name
DATABASE database_name
FUNCTION database_name
MACRO database_name.macro_name
PROCEDURE database_name.
stored_procedure_name
TABLE database_name.table_name
TYPE SYSUDTLIB.UDT_name
The keyword AUTHORIZATION, DATABASE, FUNCTION, MACRO,
PROCEDURE, TABLE, TYPE, USER, or VIEW must precede each object name.
The object name is the name of a database, specific function, macro, procedure,
table, user, or view on which logging is to be established.
You cannot log hash or join indexes. Instead, establish logging on the base tables
they belong to.
The name of a function, macro, procedure, table, UDT, user, or view must be
qualified by the name of the database or user under which that object is defined.
For TYPE, this specification is always SYSUDTLIB.
USER user_name
VIEW database_name.view_name
ANSI Compliance
BEGIN LOGGING is a Teradata extension to the ANSI SQL:2003 standard.
Authorization
You must have the EXECUTE privilege on the DBC.AccLogRule macro.
Privileges Granted Automatically
None.
Setting Up Access Logging
BEGIN LOGGING can only be performed if the DIPACC DBCSQL script, which is provided
on the software release tape, has been run to create the DBC.AccLogRule security macro, and if
the Teradata Database has been reset to initialize the logging software; otherwise, access
logging is not allowed.
Only those sites that require access logging should create the DBC.AccLogRule macro. The
feature extracts a performance penalty even if little or no logging is performed.
158
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Logging For Non-Auditing Purposes
If you need to log for non-auditing purposes, such as collecting query text for performance
and workload analysis, you should use the facilities provided by the query logging feature.
See “BEGIN QUERY LOGGING” on page 1273 and Database Administration for further
information about query logging.
How Logging Works
Each time a user named in a BEGIN LOGGING statement attempts to perform a specified
action against a specified object, an entry is logged in the system table DBC.AccLogTbl.
Possible entry data includes the type of access, the text of the request, the frequency of access,
the action requested, the name of the requesting user, and the referenced objects.
•
Logging can be ended on any action, user, or object for which logging is currently active.
•
A logging entry does not indicate that a statement was performed; rather, it indicates that
the system checked the privileges necessary to perform the statement.
Access Logging on Hash and Join Indexes
Because neither hash indexes nor join indexes cannot be accessed directly, you cannot specify
access logging for either type of object. If you need to perform access logging, specify it for the
relevant base table.
When a hash or join index is used in a query plan, the access privileges are checked for the
base table and logged appropriately.
Access Logging of External Users
All directory mappings, whether to EXTUSER or to a permanent Teradata user, are identified
by the UserId column in access log rows. External users are identified by their directory-based
identifier, which is a packed object ID, in access logs. This identifier is supplied by the Teradata
Gateway and is stored in the DBC.SessionTbl table in the AuditTrailId column.
When a user is mapped to a permanent user name, the system logs its packed object IDs
instead of the permanent user name that user is mapped to.
See Security Administration and Database Administration for further information.
Object Limits
You can specify up to 20 objects can be specified in a BEGIN LOGGING. If more than 20
objects are required, use multiple BEGIN LOGGING statements.
If more or less logging is desired, the full function of the BEGIN LOGGING statement can be
used. Also, logging can be ended on any action, user, or object for which logging is currently
active.
SQL Reference: Data Definition Statements
159
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
UDT Logging Restrictions
The following logging restrictions apply to UDTs:
•
UDTTYPE and UDTMETHOD operations are only valid when specified with either ON
DATABASE or ON USER.
If you specify a database name, it must be SYSUDTLIB.
•
UDTUSAGE operations are only valid when specified with either ON DATABASE, ON
USER, or ON TYPE.
If you specify a database name, it must be SYSUDTLIB.
Changing Options: No Access Privileges If MODIFY USER Is Used
You can enter a self-referent MODIFY USER statement. When you do so, no access privileges
are required in order to change the following options:
• AFTER JOURNAL
• DEFAULT JOURNAL TABLE
• BEFORE JOURNAL
• PASSWORD
• COLLATION
• STARTUP
• DEFAULT DATABASE
Because logging is activated by using access privileges, no logging occurs if you enter a
self-referent MODIFY USER statement.
BEGIN LOGGING Generates Entries in DBC.AccLogTbl
The rules resulting from the execution of BEGIN LOGGING statements are entered in the
system table DBC.AccLogRuleTbl. When logging is begun, the specified privilege checks
performed by the system generate entries in system table DBC.AccLogTbl. The contents of
these tables can be monitored via the system views DBC.AccLogRules and DBC.AccessLog.
Aged log entries can be purged using a DELETE statement on the view DBC.DeleteAccessLog.
Privilege checks generate log entries. MODIFY is not a privilege that can be granted, so
MODIFY is not a privilege that is checked. MODIFY operations are not logged.
To log MODIFY operations, select logging for the type of access that the MODIFY will or
might require.
Specifying such actions as DROP, INSERT, DELETE, and UPDATE can cause logging on
actions used by a MODIFY.
For example, to log MODIFY DATABASE operations, specify logging on the DROP
DATABASE privilege.
DROP DATABASE is the documented access privilege requirement for MODIFY DATABASE.
160
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
ALL, Operation, or GRANT Actions With Access Privileges
Rules related to access privileges are the following:
•
CREATE DATABASE/MACRO/PROCEDURE/TABLE/VIEW/USER and DROP
DATABASE/USER are allowed only on databases or users.
•
DROP TABLE includes ALTER TABLE.
DROP MACRO, PROCEDURE, or VIEW includes REPLACE MACRO, PROCEDURE, or
VIEW.
•
Only DROP, EXECUTE, and GRANT are allowed on macros and stored procedures.
•
DUMP, RESTORE, and CHECKPOINT are not allowed on views.
•
DATABASE, TABLE, VIEW, MACRO, PROCEDURE, and USER confer both CREATE and
DROP privileges.
•
Only CREATE FUNCTION, DROP FUNCTION, EXECUTE FUNCTION, ALTER
FUNCTION, and GRANT are allowed on user-defined functions.
These privileges apply equally to logging internal and external functions (see “CREATE
FUNCTION/ REPLACE FUNCTION” on page 222) and table functions (see “CREATE
FUNCTION (Table Form)” on page 279).
•
UDTMETHOD and UDTTYPE are allowed only for the ON DATABASE and ON USER
options. In both cases, the specified database/user must the SYSUDTLIB database.
•
UDTUSAGE is allowed for the following options:
•
ON DATABASE and ON USER.
In both cases, the specified database/user must be the SYSUDTLIB database.
•
ON TYPE.
•
Only ALTER EXTERNAL PROCEDURE, DROP PROCEDURE, EXECUTE
PROCEDURE, and GRANT are allowed on external stored procedures.
•
Role and profile access privileges do not apply to specific objects. Do not use the ON
keyword object_name option if you specify a CREATE PROFILE, CREATE ROLE, DROP
PROFILE, or DROP ROLE action.
•
The ALL option does not log all valid actions.
The following actions are not included in the ALL specification because they do not apply
to specific database objects:
•
•
•
•
ALTER REPLICATION GROUP
CREATE PROFILE
CREATE REPLICATION GROUP
CREATE ROLE
•
•
•
•
DROP PROFILE
DROP REPLICATION GROUP
DROP PROFILE
SET SESSION OVERRIDE REPLICATION
Log Entry Generated If Logging Rule Present
The system generates a log entry only if a logging rule is present for the object or for the user
whose privilege is being checked. Log entries can contain two names.
SQL Reference: Data Definition Statements
161
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Object Level Used in the Logging Statement
When a logging statement specifies logging at the database level, actions against all the tables
in that database are candidates for log entries. Also, the object level used in granting an access
privilege should be considered when specifying the object level of a logging statement.
Scenario A
Assume that DatabaseA contains several tables, and that INSERT privilege has been granted to
PUBLIC on Table1 only. Assume also that a current statement specifies “BEGIN LOGGING
ON FIRST INSERT ON DatabaseA”. Subsequently, if users other than the owner submit insert
statements against tables in DatabaseA, the log entries are:
•
A granted entry for the first insert into Table1
•
A denied entry for the first attempt at an insert into any other table in the database
When logging is specified at the database level, the same type of action against separate tables
in that database might not be logged as separate actions.
Scenario B
Assume that DatabaseA contains Table1 and Table2, and that a current BEGIN LOGGING
statement specifies logging on FIRST INSERT for DatabaseA. Next, assume that rows were
inserted into both Table1 and Table2 in the same session. The logging result would be a single
entry identifying the table that was the object of the first insert.
If the access privilege is at the database level and the logging specification is at the table level,
only actions against the table are considered for logging entries (the absence of an access
privilege at the table level does not necessarily result in a log entry).
A single log entry is generated for the table according to the results of privilege checks at both
the table level and the database level.
162
IF …
THEN …
either check succeeds
a granted entry is generated.
neither check succeeds
a denied entry is generated.
access logging is specified for a data
object (for example, a table)
log entries are generated whether that object is accessed
by name or through a view or macro.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Scenario C
A logging statement specifying FIRST SELECT ON DatabaseA.Table1 causes a log entry to be
generated only if an access statement is directly on the table.
SELECT … FROM Table_1
The following actions do not log access on DatabaseA.Table1 because the user does not
require direct access to Table 1 to perform these statements:
•
SELECT ... FROM View1_of_Table_1
•
EXECUTE MACRO_1
where Macro1 contains the statement SELECT … FROM Table1.
Users can type a MODIFY USER statement that references themselves. In such a case, no
access privileges are required to change the following options:
•
BEFORE JOURNAL
•
AFTER JOURNAL
•
DEFAULT JOURNAL TABLE
•
PASSWORD
•
STARTUP
•
COLLATION
•
DEFAULT DATABASE
Logging is activated by the use of access privileges. Therefore, no logging will take place if the
user enters a MODIFY USER statement that only changes one or more of these options for the
user himself or herself.
Rules for Using DDL Statements
BEGIN LOGGING statements must be submitted following the rules for DDL statement
usage:
•
A DDL statement cannot be combined with other statements as part of a multistatement
request.
•
A DDL statement can only be included in an explicit transaction (one or more requests
bracketed by BEGIN/END TRANSACTION statements) if it is one of the following:
•
•
The only statement in the transaction.
•
Structured as a single-statement request that appears as the last request in the
transaction.
In ANSI session mode, a DDL statement can only be included in a transaction when it is
the last single-statement request before the COMMIT statement.
SQL Reference: Data Definition Statements
163
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
When a BEGIN LOGGING statement is submitted, the system ensures that the user
submitting the request has EXECUTE privilege on the special system macro associated with
that statement (see “Setting Up Access Logging” on page 158). No checks are made for
privileges on the user or objects identified in the LOGGING statement.
If the statement cannot be performed, an error message is returned to the requester. Possible
errors include non-valid action, user, or object names.
Storage of Log Entries
Logging entries are stored in the system table DBC.AccLogTbl. The system view DBC.AccessLog
provides access to the contents of this table.
If you do not submit a BEGIN LOGGING request, the system does no query logging because
the system default is not to generate any entries on any user action.
See Security Administration for more detail on using the BEGIN LOGGING and END
LOGGING statements.
Example 1
The following example illustrates the use of BEGIN LOGGING:
BEGIN LOGGING WITH TEXT ON EACH USER, DATABASE, GRANT;
Example 2: Logging UDTs
This example begins logging all of the following attempts that failed because of insufficient
privileges:
•
•
•
•
•
ALTER TYPE
CREATE CAST
CREATE ORDERING
CREATE TRANSFORM
CREATE TYPE
•
•
•
•
•
DROP CAST
DROP ORDERING
DROP TRANSFORM
DROP TYPE
REPLACE CAST
•
•
•
•
•
REPLACE ORDERING
REPLACE TRANSFORM
method invocation
NEW specification
UDT reference
BEGIN LOGGING DENIALS ON EACH UDTTYPE;
Example 3
This example is similar to “Example 2: Logging UDTs” except that the log entries contain the
SQL text.
BEGIN LOGGING DENIALS WITH TEXT ON EACH UDTTYPE;
164
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
BEGIN LOGGING
Example 4
This example logs the first of the following operations and logs its SQL text:
•
•
•
•
•
•
ALTER METHOD
ALTER TYPE
CREATE CAST
CREATE METHOD
CREATE ORDERING
CREATE TRANSFORM
•
•
•
•
•
•
CREATE TYPE
DROP CAST
DROP METHOD
DROP ORDERING
DROP TRANSFORM
DROP TYPE
•
•
•
•
•
•
REPLACE CAST
REPLACE ORDERING
REPLACE TRANSFORM
method invocation
NEW specification
UDT reference
BEGIN LOGGING WITH TEXT ON FIRST UDTMETHOD ON DATABASE SYSUDTLIB;
Example 5
This example begins logging all UDT reference, method invocation, and NEW specification
attempts that failed because of insufficient privileges on UDTs within the SYSUDTLIB
database:
BEGIN LOGGING DENIALS ON EACH UDTUSAGE ON DATABASE SYSUDTLIB;
Example 6
This example begins logging all UDT reference, method invocation, and NEW specification
attempts that failed because of insufficient privileges on the UDT named circle.
BEGIN LOGGING DENIALS ON EACH UDTUSAGE ON TYPE SYSUDTLIB.circle;
Related Topics
FOR more about this topic …
See …
query logging
• “END LOGGING” on page 1049
• Database Administration
non-audit query logging
• “BEGIN QUERY LOGGING” on page 1273
• “END QUERY LOGGING” on page 1344
• Database Administration
external users
Security Administration
SQL Reference: Data Definition Statements
165
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
COMMENT (Comment Placing Form)
Purpose
Creates a user-defined description of a user-defined database object or definition in the data
dictionary.
Syntax
object_name
COMMENT
ON
object_kind
database_name.
'comment'
;
AS
IS
1101D022
where:
Syntax Element …
Specifies …
object_kind
an optional database object kind specification.a
The following database object kinds are valid:
•
•
•
•
•
database_name
166
AUTHORIZATION
COLUMN
DATABASE
FUNCTION
GROUP
•
•
•
•
•
MACRO
METHOD
PROCEDURE
PROFILE
ROLE
•
•
•
•
•
TABLE
TRIGGER
TYPE
USER
VIEW
the containing database or user for object_name if it is not contained by the
current database or user.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Syntax Element …
Specifies …
object_name
the name of the object to be commented on or for which a comment is to be
retrieved.
The specified object can be any of the following:
• An authorization associating a Teradata Database user with an OS server
user for a UDF, method, or external stored procedure.
• A parameter in a macro, stored procedure, or user-defined function.
• A column in a user base table or view.
• A specific function, macro, profile, role, stored procedure, base table,
trigger, or view name contained by a database or user.
• A database or user.
• A replication group.
• A UDT.
You can add a comment to a particular attribute of a structured UDT by
specifying database_name.udt_name.attribute_name.
• A method.
If you specify a method, you must use its specific method name.
If no object kind keyword precedes the object name, then the system attempts
to deduce the object from the level of qualification in the name. Use the fully
qualified name if there is any ambiguity.
Let x.y.z indicate the qualification hierarchy, with x being the highest, or more
granular, level and z the lowest, or least granular. The following table describes
the objects implied by the various qualification levels:
SQL Reference: Data Definition Statements
IF you specify this
hierarchy level …
THEN the specified object is implied to be one of the
following …
x
• database
• user
x.y
• authorization
• base table
• macro
• profile
• replication group
• role
• stored procedure
• trigger
• user-defined function
• view
within database or user x.
167
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Syntax Element …
object_name
(continued)
Specifies …
IF you specify this
hierarchy level …
THEN the specified object is implied to be one of the
following …
x.y.z
• table column
• view column
• user-defined function parameter
• macro parameter
• stored procedure parameter
• structured UDT attribute
within UDF, UDT, macro, stored procedure,
profile, role, base table, trigger, or view y which, in
turn, is within database or user x.
Replication groups do not have z-level
components.
AS
IS
an optional keyword that introduces a clause defining a comment string.
‘comment’
the commentary on or description of the object name.
Maximum string length is 255 characters from any supported client character
sets.
An existing string can be changed by specifying a new string.
If no string is specified, any string previously stored is returned.
a. The valid specifications for object_kind are not all database objects. Triggers, views, and replication
groups, for example, are definitions of actions or conceptual groups rather than database objects.
ANSI Compliance
COMMENT is a Teradata extension to the ANSI SQL:2003 standard.
168
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Authorization
The following privileges are required to place a COMMENT:
IF you want to do this …
THEN you must have this privilege …
Create or replace a comment on an object
or definition other than a replication
group, UDT, or method
DROP on the object.
Create or replace a comment on a
replication group definition
REPLCONTROL
Create or replace a comment on a method
UDTMETHOD on the SYSUDTLIB database.
Create or replace a comment on a
user-defined data type
UDTTYPE on the SYSUDTLIB database.
Retrieve a comment
None.
If the object is a column, then you must have the DROP
privilege on the object in which the column is defined.
Privileges Granted Automatically
None.
Typical Use for COMMENT
The COMMENT statement is typically used in conjunction with a CREATE statement (except
for index creating statements) to document one of the following things:
•
A newly created database object.
•
A definition for one of the following:
•
Replication group.
•
Method (UDM).
•
User-defined data type (UDT).
Note that you cannot place comments on indexes, so you cannot use this statement to place
comment strings on hash, join, or secondary indexes.
Rules for Using COMMENT
The following rules apply to using the COMMENT statement:
•
The comment-placing form of COMMENT is treated as a DDL statement for transaction
processing, so it cannot be used in 2PC session mode (see Introduction to Teradata
Warehouse for a brief description of the two-phase commit protocol).
If you specify a COMMENT statement within the boundaries of an explicit transaction in
Teradata session mode, it must be the last statement in that transaction.
SQL Reference: Data Definition Statements
169
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
•
•
•
COMMENT ON FUNCTION works for both of the following UDF types:
•
Simple external UDFs
•
Table UDFs
COMMENT ON TYPE works for both UDT types:
•
Distinct
•
Structured
COMMENT ON METHOD works for all of the following UDM types:
•
Constructor
•
Instance
•
Mutator
You must specify the specific method name for any method on which you want to place a
comment.
•
To place a comment, specify a comment string following the specification of the object
name.
•
To retrieve a comment, do not specify a comment string following the specification of the
object name.
The following table explains this behavior in more detail:
IF you …
THEN the system …
specify a
comment string
does one of the following things:
do not specify a
comment string
170
IF the specified
object has …
THEN the system …
no existing
comment
places the specified comment string for the object in
the data dictionary.
an existing
comment
replaces the existing comment in the data dictionary
with the newly specified comment string.
does one of the following things:
IF the specified
object has …
THEN the system returns …
no existing
comment
a null.
an existing
comment
the text of that comment as it is stored in the data
dictionary.
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Writing Comments Using Japanese Characters
On Japanese language sites, comments can contain single byte characters, multibyte
characters, or both from KanjiEBCDIC, KanjiEUC, or KanjiShift-JIS character sets.
For example, the following comment contains single byte and multibyte characters:
THIS COMMENT IS USED FOR TABLE TAB
Example 1: Placing a Comment
The following request can be used to specify a description of the name column in the employee
table, which is assumed to be in the current database by default because employee is not
qualified with a database name:
COMMENT ON COLUMN employee.name
IS ’Employee name, last name followed by first initial’;
Function Definition for Examples 2 and 3
Assume the following UDF definition for “Example 2” and “Example 3”:
CREATE FUNCTION Find_Text
( Searched_String VARCHAR(500), Pattern VARCHAR(500) )
RETURNS CHAR
LANGUAGE C
NO SQL
EXTERNAL
PARAMETER STYLE SQL;
Example 2
The following request places a comment on the parameter pattern of the user-defined
function Find_text:
COMMENT ON COLUMN Find_text.Pattern
IS ’The pattern matching string’;
Example 3
The following request places a comment on the definition of the user-defined function
Find_text:
COMMENT ON FUNCTION Find_text
IS ’Text search function’;
Example 4
Suppose you have a hash index named OrdHIdx defined on the orders table in the accounting
database.
You could type the following request to define a comment on the hash index OrdHIdx:
COMMENT accounting.OrdHIdx AS ’hash index on Orders’;
SQL Reference: Data Definition Statements
171
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Example 5
The following request places a comment on the replication group definition named
receivables_group:
COMMENT ON GROUP receivables_group AS
‘This is the group for receivables’;
UDT and UDM Definitions for Examples 6 and 7
Suppose you have the following UDT and UDM definitions:
CREATE TYPE address AS (
street VARCHAR(20),
zip CHARACTER(5) )
NOT FINAL
CONSTRUCTOR METHOD address( A VARCHAR(20), B CHARACTER(5) )
RETURNS address
SPECIFIC address_constructor_1
SELF AS RESULT
LANGUAGE C
PARAMETER STYLE SQL
DETERMINISTIC
NO SQL;
CREATE CONSTRUCTOR METHOD address( VARCHAR(20), CHARACTER(5) )
RETURNS address
FOR address
EXTERNAL NAME
'SO!C:\structured_lib\addr_cons.obj!F!addr_constructor';
The following example set shows how to place comments on a UDT or method:
•
“Example 6: Commenting on a UDT Definition” on page 172 shows how to place a
comment on the address type definition.
•
“Example 7: Commenting on a UDM Definition” on page 172 shows how to place a
comment on the constructor method definition having the specific method name
address_constructor_1.
Example 6: Commenting on a UDT Definition
The following request places a comment on the UDT named address:
COMMENT ON TYPE address
AS
'Type containing the Street Address and Zipcode' ;
Example 7: Commenting on a UDM Definition
The following request places a comment on the constructor method named
address_constructor_1:
COMMENT ON METHOD address_constructor_1
AS
'Constructor for the Address UDT' ;
The method name specification must be the specific name of the method.
172
SQL Reference: Data Definition Statements
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
Related Topics
See “COMMENT (Comment-Returning Form)” in SQL Reference: Data Manipulation
Statements for information about the comment returning form of the COMMENT statement.
SQL Reference: Data Definition Statements
173
Chapter 1: SQL DDL Syntax (ALTER FUNCTION - COMMENT)
COMMENT (Comment Placing Form)
174
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
SQL DDL Syntax
(CREATE AUTHORIZATION CREATE ROLE)
CHAPTER 2
This chapter describes the following statements:
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE CAST/ REPLACE CAST” on page 184
•
“CREATE DATABASE” on page 198
•
“CREATE ERROR TABLE” on page 205
•
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222
•
“CREATE FUNCTION (Table Form)” on page 279
•
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303
•
“CREATE HASH INDEX” on page 316
•
“CREATE INDEX” on page 336
•
“CREATE JOIN INDEX” on page 346
•
“CREATE MACRO/ REPLACE MACRO” on page 416
•
“CREATE METHOD” on page 431
•
“CREATE ORDERING/ REPLACE ORDERING” on page 455
•
“CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)” on
page 463
•
“CREATE PROCEDURE (SQL Form)/ REPLACE PROCEDURE” on page 529
•
“CREATE PROFILE” on page 578
•
“CREATE RECURSIVE VIEW/ REPLACE RECURSIVE VIEW” on page 587
•
“CREATE REPLICATION GROUP” on page 626
•
“CREATE ROLE” on page 641
SQL Reference: Data Definition Statements
173
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
CREATE AUTHORIZATION/
REPLACE AUTHORIZATION
Purpose
Creates the definition for an authorization object.
Authorization definitions make an association between a database user and an OS server user
identification, allowing an external routine1 to run in secure mode using the context,
privileges, and access control accrued to the specified OS user.
Syntax
CREATE
authorization_name
AUTHORIZATION
REPLACE
database_name.
DEFINER
A
DEFAULT
AS
INVOKER
USER
A
DOMAIN
'user_name'
PASSWORD
'password'
;
'domain_name'
1101B227
where:
Syntax element …
Specifies …
database_name
the optional name of a database other than the current or default in
which the authorization being defined or replaced is to be contained.
IF you specify this
authorization option …
THEN database_name must be the …
DEFINER
containing database for the UDF, table
UDF, method, or external stored
procedure.
INVOKER
user logon database.
1. External routine is a generic term for UDFs, table UDFs, UDMs, and external stored procedures.
174
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
Syntax element …
Specifies …
authorization_name
a name to be used for this authorization so it can be invoked within an
external routine definition (see “CREATE FUNCTION/ REPLACE
FUNCTION” on page 222, “CREATE FUNCTION (Table Form)” on
page 279, “CREATE METHOD” on page 431, and “CREATE
PROCEDURE (External Form)/ REPLACE PROCEDURE (External
Form)” on page 463).
The following rules apply to authorization names:
• A database can have only one INVOKER authorization name.
• A database can have only one default DEFINER authorization name.
• A database can have many non-default DEFINER authorization
names.
Because authorizations are database objects, the specified authorization
name must be unique within its containing database.
DEFINER
a keyword that associates an external routine with an operating system
server user to the database that contains the external routine.
If you specify DEFINER, then database_name must be the containing
database for the external routine.
You can specify either a DEFINER or an INVOKER, but not both.
DEFAULT
an optional keyword modifier for the DEFINER keyword that associates
this authorization with all external routines that do not specify the
authorization name in the EXTERNAL SECURITY DEFINER clause of
the following statements:
• CREATE/REPLACE FUNCTION (see “CREATE FUNCTION/
REPLACE FUNCTION” on page 222).
• CREATE/REPLACE FUNCTION (Table Form) (see “CREATE
FUNCTION (Table Form)” on page 279).
• CREATE PROCEDURE (External Form) (see “CREATE
PROCEDURE (External Form)/ REPLACE PROCEDURE (External
Form)” on page 463).
You can assign only one default DEFINER object per database. All
others must have specific definer names.
If a default DEFINER already exists for the current or specified
database, the system aborts the CREATE AUTHORIZATION request
and returns a message to the requestor.
INVOKER
a keyword that associates an operating system user to the database user
who invokes the external routine.
If you specify INVOKER, then database_name must be the logon
database for the user.
You can assign only one INVOKER authorization name per database.
You can specify either a DEFINER or an INVOKER, but not both.
SQL Reference: Data Definition Statements
175
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
Syntax element …
Specifies …
DOMAIN
a keyword that specifies that the single-quoted text string that follows is
the name of the operating system domain to which the specified user
belongs.
The domain clause has the following characteristics:
• It is mandatory for Windows systems.
• It is not used by UNIX and Linux systems.
If you specify a domain clause for a UNIX system, it is ignored.
• It is a Windows-specific operating system term that has nothing to
do with the domains used in database management systems, where
the term relates to a set of valid value ranges for a column as
specified by a predefined data type or UDT (see Database Design for
more information about relational domains).
‘domain_name’
the single-quoted name of the Windows operating system domain to
which the specified user belongs.
If the user does not have a domain, then specify an empty string, for
example DOMAIN ‘’.
USER
a keyword that specifies that the single-quoted text string that follows is
the name of the operating system user to whom this authorization
applies.
‘user_name’
the single-quoted name of the operating system user being assigned an
authorization name.
PASSWORD
a keyword that specifies that the single-quoted text string that follows is
the name of the operating system server password assigned to
user_name.
‘password’
the single-quoted operating system server password associated with
user_name.
The password is used to authenticate the user when the secure server
process is created. Best practices suggest that any session that uses this
statement should be set up to use the encrypted transport protocol (see
Security Administration for details).a
a. While it is never desirable for a password to be typed in the clear, it only becomes an issue when you
enter your password using an interface such as BTEQ. The issue becomes moot if you are prompted
to enter your password by an application that requests the information in a secure manner such as a
GUI or World Wide Web interface that displays ASTERISK characters to represent the password as it
is typed. This is the recommended practice for all security conscious sites.
ANSI Compliance
CREATE AUTHORIZATION is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
You must have either the CREATE/REPLACE AUTHORIZATION or AUTHORIZATION
privilege to perform the CREATE/REPLACE AUTHORIZATION statement.
176
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
Privileges Granted Automatically
DROP AUTHORIZATION to the creator of the authorization.
Providing Security for User-Written External Routines
Authorization definitions permit users to issue operating system I/O calls from within an
external routine (see “CREATE FUNCTION/ REPLACE FUNCTION” on page 222, “CREATE
METHOD” on page 431, and “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463). The ANSI SQL-2003 specification collectively
refers to user-written non-SQL modules as external routines.
The Teradata Database requires any external routine that is designed to perform operating
system I/O to run in protected mode as a separate process than runs under an explicitly
specified user ID (see “Protected and Unprotected Execution Modes” on page 240).
The system enforces this restriction for the following reasons:
•
Operating system I/O calls need a context to be able to access data and to determine which
data they can access. The only way to do this is to run the external routine as a separate
process under the authorization of a specific user.
•
It is not appropriate to permit an external routine to execute in the context of either of the
following, both of which run in the root context under UNIX and Linux and in the system
mode context under Windows:
•
An AMP Worker Task.
•
The Parser component of the parsing engine.
These are not appropriate for the following reasons:
•
Running in root context under UNIX or Linux gives a function super user privileges.
•
Running in system mode context under Windows presents similar issues to those of a
UNIX super user.
•
An AWT thread can be aborted by means of a simple transaction abort, which in turn
can cause memory leaks and hanging file handles.
None of this behavior is appropriate for a user-written routine. Authorization objects provide
a flexible, yet robust, scheme for providing the authorizations required by these external
routines without exposing the system to the these potential problems.
The principal difference between an external routine running in protected mode (see “ALTER
FUNCTION” on page 21, “ALTER METHOD” on page 28, or “ALTER PROCEDURE
(External Form)” on page 34) or in secure mode is that when an external routine runs in
protected mode, it always runs as the OS user tdatuser, while an external routine that runs in
secure mode can run as any OS user you want to associate with an external authorization.
While tdatuser has no special privileges, an OS user associated with an external authorization
can have any privileges on OS files you want to assign to it. All that is required is that the OS
user with special privileges be specified in the EXTERNAL SECURITY clause of the SQL
definition for the external routine associated with it (see “CREATE FUNCTION/ REPLACE
FUNCTION” on page 222, “ALTER METHOD” on page 28, or “CREATE PROCEDURE
(External Form)/ REPLACE PROCEDURE (External Form)” on page 463 for details).
SQL Reference: Data Definition Statements
177
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
DEFINER and INVOKER Authorizations
An external routine with an EXTERNAL SECURITY clause DEFINER authorization always
uses the OS user authorization that is associated with the creator of the authorization object.
An external routine with an EXTERNAL SECURITY clause INVOKER authorization uses the
OS user authorization that is associated with the database user who invokes it.
Both routines require external authorization. The difference is in which OS user authorization
the routine uses when it runs:
•
All use the same OS user authorization, that of the user who created the authorization,
when the routine is defined with a DEFINER authorization.
•
All use a different OS user authorization, that of the user who invokes the routine, when
the routine is defined with an INVOKER authorization.
The following table summarizes these differences:
WHEN an external routine is to be run with the …
THEN you should specify this type of
authorization …
same OS user authorization independent of the user who
runs the routine
DEFINER.
OS user authorization as specified by the user who runs the
routine
INVOKER.
Authorization Rules
•
When you submit a CREATE AUTHORIZATION statement, the system validates the
authorization. The system verifies the following items, and if any of them is false, the
authorization attempt returns an error:
•
The OS password is validated on each node.
•
The OS server user must belong to the OS group2 named tdatudf or its equivalent.3
tdatudf need not be the primary group for the OS server user, but that user must be a
member of the group.
The tdatudf group or its equivalent as defined by the cufconfig utility (see Utilities) is
used by protected mode external routines and must always exist. You can change the
tdatudf group assignment for external routines using their EXERNAL SECURITY
clause.
The best practice is to make this group serve only the external routines that specify an
EXTERNAL SECURITY clause and not use it for any other purpose.
•
For Windows systems, the specified OS user name must exist in the specified domain
on all database nodes.
2. Consult your Linux, UNIX, or Windows operating system documentation, as appropriate, for the specific
definitions of group, local group, and so on.
3. Note that tdatudf is the default group name, created during the installation of the Teradata Database. You
can change the default OS group to either an entirely new group or an existing group using the cufconfig
utility (see Utilities).
178
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
•
The authentication process uses whichever authentication methods are set up by the site
for the database server. If the site is using a Windows domain server such as Kerberos to do
authentication, then the specified user is validated using that method. The same is true for
UNIX- and Linux-based authentications.
Authentication is automatic as long as the server nodes are part of the global
authentication process. If they are not part of that process, then you must create a local OS
user4 on each node.
•
You cannot specify CREATE AUTHORIZATION in a macro (see “CREATE MACRO/
REPLACE MACRO” on page 416) because the authorization password is not saved in
either encrypted or unencrypted form. This is because doing so would compromise the
security of the OS logon user ID.
•
Any external routine that is designed to access external data must run in either secure or
protected mode as a separate process under the user ID of an OS server user. There are
several reasons for doing this, primarily because the OS I/O calls need a context for
accessing data and determining which data it has access to. The only way to do this is to
run the external routine as a separate process under the authorization of a specific OS user.
When you create an external routine that includes an EXTERNAL SECURITY clause, the
name of the OS user specified in that clause must be a member of the group specified for
the UDF GDO, tdatudf. The system creates this group by default during the installation of
the Teradata Database.
You control group membership using the cufconfig utility (see Utilities). You can specify a
different group to handle your external security routines, but the tdatudf group must:
•
Always exist.
•
Never be altered.
The reason for these restrictions is that the system always uses the tdatudf group to run
protected or secure mode routines. When an external routine runs in protected or secure
mode, it always runs as user tdatuser.
The user named tdatuser must be a member of the tdatudf group, but it has no special
system privileges. This is true regardless of the group name specified by the
SecureGroupMembership field of the cufconfig utility (see Utilities).
If an external routine runs under a different user than tdatuser, that user name must
belong to the group specified by the SecureGroupMembership field of cufconfig.
The following table summarizes the different users associated with protected and secure
mode servers:
WHEN an external routine runs in this mode …
IT runs as this user …
protected
tdatuser.
secure
the OS user associated with the authorization
for the external routine.
4. A local OS user is any user that must be created manually. Local OS users are not associated with a domain.
SQL Reference: Data Definition Statements
179
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
In both protected and secure modes, the system sets the server process up on a PE or AMP
vproc as needed to execute the external routine.
You can run a maximum of 20 protected mode servers and 20 secure mode servers per
AMP or PE. To clarify, you can run up to 40 “protected” mode servers concurrently per
AMP or PE, but not more than 20 each of the protected and secure mode types.
•
The number of server processes that can be set up on any one vproc is limited. The limit is
determined by the UDF GDO, which is controlled by the cufconfig utility (see Utilities).
When modifying the cufconfig fields, keep in mind that each protected or secure mode
process uses its own private shared memory, which requires private disk swap space. Each
process requires 256 K bytes of disk space.
For example, if two protected mode servers are allocated per vproc and there are 8 vprocs
on the node, then 4 megabytes of system disk file space are required, as indicated by the
following equation:
Number of vprocs Number of protected mode servers 256 K bytes
Total swap space required = ------------------------------------------- × ----------------------------------------------------------------------------------- × ----------------------------Node
vproc
server
By substitution, for a system defined with 2 protected mode servers per vproc, 4 megabytes
of disk swap space are required:
8 vprocs 2 Servers 256 K bytes
Total swap space required = -------------------- × ---------------------- × ----------------------------- = 4 Mbytes per Node
Node
vproc
Server
For a system defined with 20 protected mode servers per vproc, 40 megabytes of disk swap
space are required:
8 vprocs 20 Servers 256 K bytes
Total swap space required = -------------------- × ------------------------- × ----------------------------- = 40 Mbytes per Node
Node
vproc
Server
The system does not allocate space until an external routine is executing that requires the
space. If you run 10 sessions, and each one executes a query that uses a UDF at the same
instance, then the system creates 10 protected mode servers per vproc.
If, however, the 10 sessions execute the UDF queries sequentially, then only one protected
mode process per vproc needs to be created. Once a protected mode server is set up, it
remains in existence until the database restarts. If any servers are not used, the system
swaps them out to disk, so they do not consume any physical memory resources.
What CREATE AUTHORIZATION Does
The purpose of an authorization object is to specify the user context to use when running an
external routine that performs operating system I/O operations (see “CREATE FUNCTION/
REPLACE FUNCTION” on page 222, “CREATE FUNCTION (Table Form)” on page 279,
“CREATE METHOD” on page 431, “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463, and SQL Reference: UDF, UDM, and External
Stored Procedure Programming).
Authorization objects associate a user with an OS server user ID. With an OS server user ID, a
user can log onto a Teradata Database node as a native operating system user and so be able to
run external routines that perform OS-level I/O operations.
180
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
You must create an authorization object for any external routine that has an EXTERNAL
SECURITY clause as part of its definition. In particular, you must define authorization objects
for the following users and situations:
•
A user who needs to run external routines that contain an INVOKER security clause.
•
A user who needs to be the definer of any external routine modules that contain the
DEFINER external clause.
See “DEFINER and INVOKER Authorizations” on page 178.
Without the appropriate authorization objects having been created, none of the external
routines containing an EXTERNAL SECURITY clause can run. Attempts to execute the
external routine return an exception message to the requestor and the call to the external
routine aborts.
When you submit a CREATE AUTHORIZATION statement, the system validates the values
for the specified user variables. If the specified user object has not yet been created on all
database nodes, then the statement fails and returns an error message to the requestor.
CREATE AUTHORIZATION also fails if any of the other information you specified is not
correct.
The system permits only three failed attempts to create an authorization object. After three
failed attempts, the Teradata Database returns an appropriate error message to the requestor.
This restriction is implemented to thwart malicious attempts to circumvent system security by
submitting CREATE AUTHORIZATION statements in a program loop to iterate different
combinations of user names and passwords.
In order to attempt to make another attempt to perform the statement, you must first log off
the system and then log back on. The DBA also has the option of activating access logging on
CREATE AUTHORIZATION in order to track suspicious attempts to perform it.
Rules for Authorization Names
Names for authorization objects must obey the following set of rules:
•
Like all other Teradata Database objects, authorization names are limited to 30 characters,
including all uppercase and lowercase alphanumeric characters and the following
non-alphanumeric characters:
•
DOLLAR SIGN ($)
•
NUMBER SIGN (#)
•
LOW LINE ( _ )
Teradata Database names have the following additional restrictions:
•
•
They cannot begin with a digit.
•
They cannot be a keyword.
An authorization object name must be unique within its containing database.
SQL Reference: Data Definition Statements
181
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
•
Authorizations belong to the database or user in which they are created and are not valid
in other databases or users.
•
A database can be associated with only one INVOKER authorization object name.
•
A database can be associated with only one default DEFINER authorization object name.
•
A database can be associated with many non-default DEFINER authorization object
names.
Example 1
This example creates an INVOKER authorization object with the name sales for the domain
eastsales, the user name sam johnson, and the user password tercesym.
CREATE AUTHORIZATION sales AS INVOKER
DOMAIN ‘eastsales’
USER ‘sam johnson’
PASSWORD ‘tercesym’;
The system uses this OS server user context to execute all external routines that contain an
EXTERNAL SECURITY INVOKER clause when invoked by the database user that created this
authorization.
Example 2
The following example creates a DEFINER authorization object with the name
sales_processing for the domain DistrictA, the user name salesmng, and the user password
mysecret.
CREATE AUTHORIZATION sales_processing AS DEFINER
DOMAIN ‘DistrictA’
USER ‘salesmng’
PASSWORD ‘mysecret’;
The system uses this OS server user context to execute all external routines that contain an
EXTERNAL SECURITY DEFINER clause when run under the same OS user authorization
independent of the user who runs the routine.
182
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE AUTHORIZATION/ REPLACE AUTHORIZATION
Example 3
This example creates a definer authorization with the name accounting in the SYSLIB database
for the client user name accdept and user password nesuahkcotsk.
CREATE AUTHORIZATION SYSLIB.accounting AS DEFINER DEFAULT
USER ‘accdept’
PASSWORD ‘nesuahkcotsk’;
The example associates accounting as the DEFAULT authorization in the SYSLIB database with
the specified client user name accdept.
Because accdept is the DEFAULT authorization object, the system associates it with all external
routines that contain the EXTERNAL SECURITY DEFINER clause. All external routines in
database SYSLIB that contain an EXTERNAL SECURITY DEFINER clause are executed using
the user context defined by this statement.
Recall that there can only be one default definer object in a database. All others must have
specific names. If the DEFAULT already exists, this statement aborts and returns an error to
the requestor.
Example 4
This example creates a specific definer authorization name sales with all external routines that
contain the external security clause EXTERNAL SECURITY DEFINER sales. The
authorization object name sales is part of the text specified for the external security clause.
This specification causes the system to validate the authorization object SYSLIB.sales in the
data dictionary and then, once it has been validated, to use the specified user context to run
the external routine.
CREATE AUTHORIZATION SYSLIB.sales AS DEFINER
USER ‘SalesDept’
PASSWORD ‘ikcerednep’;
Related Topics
The following topics document the EXTERNAL SECURITY clause for the various external
routine types:
•
For UDFs, see “External Security Clause” on page 272.
•
For external stored procedures, see “EXTERNAL SECURITY Clause” on page 514.
See “DROP AUTHORIZATION” on page 1001 for information about dropping the definition
for an authorization object.
See “CREATE FUNCTION/ REPLACE FUNCTION” on page 222, “CREATE FUNCTION
(Table Form)” on page 279, and “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463 for information about how authorization
objects are used with external UDFs and stored procedures.
See the cufconfig utility in Utilities for information about how to configure external routine
server processes and how to alter secure group membership.
SQL Reference: Data Definition Statements
183
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
CREATE CAST/
REPLACE CAST
Purpose
Creates or replaces a cast operation for a UDT.
Syntax
CREATE
CAST
(
source_predefined_data_type
A
AS
source_UDT_name
REPLACE
SYSUDTLIB.
A
target_predefined_data_type
)
WITH
B
target_UDT_name
SYSUDTLIB.
B
specific_method_name
SPECIFIC METHOD
method_name
METHOD
FOR UDT_name
(
,
INSTANCE
C
(
data_type
UDT_name
SPECIFIC FUNCTION
FUNCTION
specific_function_name
function_name
(
,
(
data_type
UDT_name
C
AS ASSIGNMENT
;
1101A358
where:
Syntax element …
Specifies …
source_data_type
either a structured or distinct UDT or any valid predefined data
type.
Either source_data_type or target_data_type or both must be a UDT.
If source_data_type is a predefined data type, then its cast routine
must be a cast function (see “SPECIFIC FUNCTION
specific_function_name” on page 185).
184
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Syntax element …
Specifies …
target_data_type
either a structured or distinct UDT or any valid predefined data
type.
Either target_data_type or source_data_type or both must be a UDT.
SPECIFIC FUNCTION
specific_function_name
FUNCTION function_name
[(data_type)]
the name or specific name of the UDF to be used to convert
source_data_type to target_data_type. x must specify a unique
function.
If you do not specify a set of data types for a function name, then
the specified function must be the only UDF with that name in the
database.
The specified function must satisfy the following conditions:
• It can have only one parameter.
Its parameter data type must be the same as source_data_type.
• Its result data type must be the same as target_data_type.
• It must be defined to be DETERMINISTIC.
• Its function name must identify a UDF in the SYSUDTLIB
database.
SPECIFIC METHOD
SYSUDTLIB.specific_method_
name
[INSTANCE] METHOD
[database_name.]
method_name [(data_type)]
FOR UDT_name
the name of the method to be used to convert a source UDT value
to the target data type.
If you specify a specific method, then a method with the same
specific method name must be defined in the SYSUDTLIB
database.
If you specify a method, then a method associated with the
specified UDT_name must exist with the same signature.
The method must satisfy the following conditions:
• Its associated UDT is the same as the source data type.
• Its declared parameter list is empty.
• Its result data type is the same as the target data type.
• It must be defined to be DETERMINISTIC.
If no method is found, an error is returned.
FOR UDT_name
SQL Reference: Data Definition Statements
the name of the UDT associated with method_name.
185
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Syntax element …
Specifies …
AS ASSIGNMENT
to implicitly invoke the specified cast routine on an assignment
operation if both of the following statements are true:
• The source data type of the assignment is compatible with the
source data type of the cast result.
• The target data types are identical.
Note that an assignment operation is defined to be any of the
following operations:
• INSERT
• UPDATE
• parameter passing
You can disable this functionality by means of the
DisableImplCastForSysFuncOp DBSControl flag (see “Using the
AS ASSIGNMENT Clause To Make a Cast Operation Implicitly
Invokable” on page 188 and Utilities for details).
Caution:
Be very careful if you are performing a REPLACE CAST
statement because the system updates the UDTCast
dictionary to reflect the value of the AS ASSIGNMENT
flag. See “Difference Between CREATE CAST and
REPLACE CAST” on page 187.
ANSI Compliance
CREATE CAST is ANSI SQL:2003-compliant with extensions.
REPLACE CAST is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
You must have either the UDTTYPE or UDTMETHOD privilege on the SYSUDTLIB database
to create or replace a cast.
If you specify a cast_function, then you must also have the EXECUTE FUNCTION privilege
on the UDF, and it must be contained within the SYSUDTLIB database.
Privileges Granted Automatically
None.
186
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Difference Between CREATE CAST and REPLACE CAST
If you perform a CREATE CAST statement, there must not be an existing user-defined cast
that performs the same conversion, else the statement aborts and returns an error to the
requestor.
IF you perform a REPLACE CAST statement and
there is …
THEN the system …
no existing user-defined cast that performs the
specified conversion
creates a new user-defined cast.
an existing user-defined cast that performs the
specified conversion
replaces the existing user-defined cast definition
with the newly defined cast routine.
The result is the same as if you had performed a
CREATE CAST statement with all the same
specifications.
If the cast routine is a method, then that method must be already be defined, else the system
aborts the request, returns an error to the requestor, and does not register the method for
casting.
About UDT Casts
A cast operation converts the specified source_data_type to the specified target_data_type
using the specified cast_function or cast_method routine analogous to the CAST operator used
to convert predefined data types (see SQL Reference: Functions and Operators for more
information about the CAST operator). At least one of source_data_type or target_data_type
must be a UDT (see “CREATE TYPE (Distinct Form)” on page 906 and “CREATE TYPE
(Structured Form)” on page 927).
Casts are the mechanism the system uses to make conversions in either direction between a
UDT and another data type, which might or might not be another UDT. UDTs can have
multiple casts, where each cast supports the conversion for a particular source-target
combination.
For example, the UDT named circle_type might have the following four separate casts:
•
circle_type to VARCHAR
•
VARCHAR to circle_type
•
circle_type to VARBYTE
•
VARBYTE to circle_type
Once you have created a user-defined cast, it is immediately available for use with the SQL
CAST function (see SQL Reference: Functions and Operators). For example, if you have defined
a cast to convert a circle UDT to a VARCHAR(40), then you can specify the following cast
operation:
CAST(circle_udt_expression AS VARCHAR(40))
SQL Reference: Data Definition Statements
187
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
The system automatically and implicitly supports casts from or to a predefined data type when
you cast a compatible predefined type to the appropriate predefined type serving as the cast
source of target type.
The scope of operations under which the system applies UDT-related implicit casts is a subset
of the scope of operations under which traditional predefined data type-related implicit casts
are applied (see SQL Reference: Functions and Operators).
For example, consider the following equality comparison in a WHERE clause:
WHERE myUdt = NEW CircleUdt(1,1,9)
This is not within the scope of the implicit casts the system supports because it is not an
assignment operation, supported system operator, or supported predefined function, so no
implicit casts is applied. In such cases, you must specify explicit cast operations to ensure that
the UDTs being compared are identical.
Using the AS ASSIGNMENT Clause To Make a Cast Operation Implicitly
Invokable
You can make a user-defined cast implicitly invokable by including the AS ASSIGNMENT
clause in its CREATE CAST statement. When you define a cast operation in this way, the
system implicitly invokes the cast for all assignment operations.5
You can disable this functionality by setting the DisableImplCastForSysFuncOp DBSControl
flag to TRUE (see Utilities for details).6 This action disables implicit UDT-to-predefined data
type casts for built-in system functions and operators.
If DisableImplCastForSysFuncOp is set to 0x01 and you attempt to pass a UDT into a built-in
system function or operator, the system aborts the request and returns an error to the
requestor.
This flag only affects built-in system functions and operators. The system continues to invoke
implicit casts for insert and update operations and for parameter passing with respect to
UDFs, UDMs, and stored procedure operations when the DisableImplCastForSysFuncOp flag
is set to FALSE.
See Utilities for information about setting the value for the DisableImplCastForSysFuncOp
flag.
5. An assignment operation is defined to be an INSERT, MERGE, UPDATE, or parameter passing operation.
6. The default value for this flag is FALSE, meaning that implicit casting is enabled.
188
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Creating Parallel Cast and Transform Functionality
Best practices suggest that it is a good idea to replicate all transform group functionality (see
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855) with the equivalent cast
functionality. In other words, create parallel functionalities for the two conversion types.
The following table explains this more explicitly:
Cast Functionality
Equivalent Transform Functionality
External predefined data type to UDT cast
External predefined data type to UDT tosql transform
UDT to external predefined data type cast
UDT to external predefined data type fromsql transform
This is especially recommended if you want to use a UDT in the same way you would use any
other data type, especially with respect to load utilities and the USING row descriptor, it is
recommended that the type developer back up their tosql and fromsql functionality with
equivalent external type (predefined) to UDT and UDT to external type (predefined) implicit
casts, respectfully.
The simplest way to accomplish these equivalencies is to reference the same external routines
in both the CREATE TRANSFORM and CREATE CAST statements for the same UDT.
The implications of this best practice differ for distinct and structured UDTs as follows:
FOR this kind of UDT …
You must do the following work to create parallel casting and transform
functionality…
distinct
none if you plan to use the system-generated casts and transforms.
However, if you decide to write your own external cast and transform
routines for the UDT, you must create the parallel cast and transform
functionalities explicitly using the CREATE CAST and CREATE
TRANSFORM statements, respectively.
structured
create the necessary casts and transforms explicitly, using the same
external routines for both.
See “CREATE CAST/ REPLACE CAST” on page 184 and “CREATE TRANSFORM/ REPLACE
TRANSFORM” on page 855 for information about how to use those statements.
SQL Reference: Data Definition Statements
189
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Possible Predefined Type Source and Target User-Defined Cast
Combinations
The following table lists the acceptable inputs for a predefined data type-to-UDT cast and
acceptable targets for a UDT-to-predefined data type cast.
The table shows that for user-defined casts, the system supports a degree of implicit
predefined data type-to-predefined type conversions.
Source Input
Source Data Type of
CAST Definition
BYTEINT
BYTEINT
SMALLINT
SMALLINT
INTEGER
Target Data Type of
CAST Definition
UDT
Target Output
UDT
INTEGER
BIGINT
DECIMAL
BIGINT
NUMERIC
DECIMAL
REAL
NUMERIC
FLOAT
REAL
DOUBLE PRECISION
FLOAT
DATE
DOUBLE PRECISION
CHARACTER
VARCHAR
BYTE
BYTE
VARBYTE
VARBYTE
BLOB
190
BLOB
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Source Input
Source Data Type of
CAST Definition
CHARACTER
CHARACTER
VARCHAR
VARCHAR
CLOB
Target Data Type of
CAST Definition
UDT
Target Output
UDT
CLOB
BYTEINT
SMALLINT
INTEGER
BIGINT
DECIMAL
NUMERIC
REAL
FLOAT
DOUBLE PRECISION
DATE
DATE
DATE
BYTEINT
SMALLINT
INTEGER
BIGINT
DECIMAL
NUMERIC
REAL
FLOAT
DOUBLE PRECISION
DATE
TIME
TIME
TIME WITH TIME
ZONE
TIME WITH TIME
ZONE
CHARACTER
VARCHAR
TIMESTAMP
TIMESTAMP
TIMESTAMP WITH
TIME ZONE
TIMESTAMP WITH
TIME ZONE
CHARACATER
VARCHAR
SQL Reference: Data Definition Statements
191
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Source Input
Source Data Type of
CAST Definition
INTERVAL YEAR
INTERVAL YEAR
INTERVAL YEAR TO
MONTH
INTERVAL YEAR TO
MONTH
INTERVAL MONTH
INTERVAL DAY
INTERVAL DAY TO
HOUR
INTERVAL DAY TO
HOUR
INTERVAL DAY TO
SECOND
INTERVAL HOUR
INTERVAL HOUR TO
MINUTE
INTERVAL HOUR TO
SECOND
UDT
UDT
INTERVAL DAY TO
MINUTE
INTERVAL DAY TO
SECOND
INTERVAL HOUR
INTERVAL HOUR TO
MINUTE
INTERVAL MINUTE
INTERVAL HOUR TO
SECOND
INTERVAL MINUTE
TO SECOND
INTERVAL MINUTE
INTERVAL SECOND
Target Output
INTERVAL MONTH
INTERVAL DAY
INTERVAL DAY TO
MINUTE
Target Data Type of
CAST Definition
INTERVAL MINUTE
TO SECOND
INTERVAL SECOND
UDT1
UDT1
UDT2
UDT2
UDT
UDT
BYTEINT
BYTEINT
SMALLINT
SMALLINT
INTEGER
INTEGER
BIGINT
BIGINT
DECIMAL
DECIMAL
NUMERIC
NUMERIC
REAL
REAL
FLOAT
FLOAT
DOUBLE PRECISION
DOUBLE PRECISION
CHARACTER
VARCHAR
DATE
192
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Source Input
UDT
Source Data Type of
CAST Definition
UDT
Target Data Type of
CAST Definition
Target Output
BYTE
BYTE
VARBYTE
VARBYTE
BLOB
BLOB
CHARACTER
CHARACTER
VARCHAR
VARCHAR
CLOB
CLOB
BYTEINT
SMALLINT
INTEGER
BIGINT
DECIMAL
NUMERIC
REAL
FLOAT
DOUBLE PRECISION
DATE
TIME
TIME WITH TIME
ZONE
TIMESTAMP
TIMESTAMP WITH
TIME ZONE
DATE
DATE
BYTEINT
SMALLINT
INTEGER
BIGINT
DECIMAL
NUMERIC
REAL
FLOAT
DOUBLE PRECISION
CHARACTER
VARCHAR
SQL Reference: Data Definition Statements
193
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Source Input
UDT
Source Data Type of
CAST Definition
UDT
Target Data Type of
CAST Definition
Target Output
TIME
TIME
TIME WITH TIME
ZONE
TIME WITH TIME
ZONE
TIMESTAMP
TIMESTAMP
TIMESTAMP WITH
TIME ZONE
TIMESTAMP WITH
TIME ZONE
INTERVAL YEAR
INTERVAL YEAR
INTERVAL YEAR TO
MONTH
INTERVAL YEAR TO
MONTH
INTERVAL MONTH
INTERVAL MONTH
INTERVAL DAY
INTERVAL DAY
INTERVAL DAY TO
HOUR
INTERVAL DAY TO
HOUR
INTERVAL DAY TO
SECOND
INTERVAL DAY TO
SECOND
INTERVAL HOUR
INTERVAL HOUR
INTERVAL HOUR TO
MINUTE
INTERVAL HOUR TO
SECOND
INTERVAL HOUR TO
MINUTE
INTERVAL HOUR TO
SECOND
INTERVAL MINUTE
INTERVAL MINUTE
INTERVAL MINUTE
TO SECOND
INTERVAL MINUTE
TO SECOND
INTERVAL SECOND
INTERVAL SECOND
194
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Cast Requirements for Teradata Utilities
Some Teradata utilities require you to define casts to permit them to process UDT data. The
following list explains what those requirements are:
•
Database utilities
None of the server-based utilities have transform requirements.
The USING modifier requires you set up implicit casts for casting a predefined external
data type to a UDT. See SQL Reference: Data Manipulation Statements for details.
•
Teradata Tools and Utilities
The following table explains the casting requirements for various Teradata Tools and
Utilities:
Utility
Cast Requirements
Archive/Recovery
None
FastExport
None
FastLoad
None
MultiLoad
None
Teradata Parallel Data Pump (TPump)
Implicit cast from a predefined external
data type to a UDT.
Teradata Parallel Transporter:
None
• UPDATE
• LOAD
• EXPORT
Teradata Parallel Transporter STREAMS
Implicit cast from a predefined external
data type to a UDT.
Example 1
The following CREATE CAST statement creates a cast operation that converts the source data
type circle to the target data type VARCHAR(32) using the method having the specific method
name circleToVarchar.
CREATE CAST (circle AS VARCHAR(32))
WITH SPECIFIC METHOD SYSUDTLIB.circleToVarchar
SQL Reference: Data Definition Statements
195
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
Example 2
The following CREATE CAST statement creates a cast operation that converts the source data
type euro to the target data type VARCHAR(20) using the method euroString. The casting
routine is defined so it is implicitly invoked on an assignment operation assuming the
necessary conditions are met for the assignment (see “AS ASSIGNMENT” on page 186 for
more information).
CREATE CAST (euro AS VARCHAR(20))
WITH METHOD SYSUDTLIB.euroString( ) FOR euro
AS ASSIGNMENT
Example 3
The following CREATE CAST statement creates a cast operation that converts the source data
type VARCHAR(32) to the target data type circle using the UDF having the specific function
name VarcharTocircle.
CREATE CAST (VARCHAR(32) AS circle)
WITH SPECIFIC FUNCTION SYSUDTLIB.VarcharTocircle
Related Topics
See the following statements, as appropriate, for additional information about user-defined
data types:
196
•
“ALTER METHOD” on page 28
•
“ALTER TYPE” on page 142
•
“CREATE METHOD” on page 431
•
“CREATE ORDERING/ REPLACE ORDERING” on page 455
•
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855
•
“CREATE TYPE (Distinct Form)” on page 906
•
“CREATE TYPE (Structured Form)” on page 927
•
“DROP CAST” on page 1003
•
“DROP ORDERING” on page 1032
•
“DROP TRANSFORM” on page 1041
•
“DROP TYPE” on page 1043
•
“REPLACE METHOD” on page 1112
•
“HELP CAST” on page 1427
•
“HELP METHOD” on page 1493
•
“HELP TRANSFORM” on page 1557
•
“HELP TYPE” on page 1563
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE CAST/ REPLACE CAST
See the following statements, as appropriate, for additional information about user-defined
functions:
•
“ALTER FUNCTION” on page 21
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222
•
“CREATE FUNCTION (Table Form)” on page 279
•
“DROP AUTHORIZATION” on page 1001
•
“DROP FUNCTION” on page 1013
•
“HELP FUNCTION” on page 1464
See SQL Reference: Functions and Operators for information about the standard SQL CAST
function and its uses with predefined data types.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for information
about coding methods for external routines to support UDMs and UDFs.
See the following Teradata Tools and Utilities manuals for details about how the software they
document deals with UDTs:
•
Teradata Archive/Recovery Utility Reference
•
Basic Teradata Query Reference
•
Teradata FastExport Reference
•
Teradata FastLoad Reference
•
Teradata Driver for the JDBC Interface User Guide
•
Teradata MultiLoad Reference
•
ODBC Driver for Teradata User Guide
•
Teradata Preprocessor2 for Embedded SQL Programmer Guide
•
Teradata Parallel Data Pump Reference
•
Teradata Parallel Transporter Reference
•
Teradata Tools and Utilities Access Module Reference
SQL Reference: Data Definition Statements
197
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
CREATE DATABASE
Purpose
Creates a database in which other database objects can be created.
Syntax
name
CREATE DATABASE
A
AS
FROM database_name
CD
,
A
PERMANENT
= n
;
BYTES
PERM
SPOOL = n
BYTES
TEMPORARY = n
bytes
ACCOUNT =
'account_ID'
FALLBACK
NO
PROTECTION
JOURNAL
NO
BEFORE
DUAL
AFTER JOURNAL
NO
DUAL
LOCAL
NOT LOCAL
table_name
DEFAULT JOURNAL TABLE =
database_name.
1101E030
where:
198
Syntax Element …
Specifies …
name
the name of the new database.
database_name
the name of the immediate owning user or database. The default is the
user name associated with the current session.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
Syntax Element …
Specifies …
PERMANENT = n BYTES
the total number of bytes to be reserved for permanent storage of the
new database. The space is taken from unallocated space in the
database of the immediate owner.
The number of bytes can be entered as an integer, decimal, or floating
point value.
This option must be specified. There is no default.
SPOOL = n BYTES
the number of bytes to be allowed for spool and volatile temporary
files. The default is the largest value that is not greater then the owner
spool space and that is a multiple of the number of AMPs on the
system. n must not exceed the owner spool space.
The number of bytes can be entered as an integer, decimal, or floating
point value.
TEMPORARY = n
a definition for how many bytes are to be allowed by default for
creating materialized global temporary tables by users within this
database. Note that temporary space is reserved prior to spool space
for any user defined with this characteristic.
Disk usage for a materialized global temporary table is charged to the
temporary space allocation of the user who referenced the table.
The number of bytes can be entered as an integer, decimal, or floating
point value.
If no default temporary space is defined for a database, then the space
allocated for any materialized global temporary tables created in that
database is set to the maximum temporary space allocated for its
immediate owner.
ACCOUNT =
‘account_ID’
the account to be charged for the space used by this database. If not
specified, it defaults to the account identifier of the immediate owner
database.
An account ID is a Teradata Database SQL word and can contain up to
30 APOSTROPHE-delimited characters.
See SQL Reference: Fundamentals, for a description of Teradata
Database SQL words and a list of the valid characters they can contain.
FALLBACK
PROTECTION
NO FALLBACK
PROTECTION
whether to create and store a duplicate copy of each table created in
the new database. The default value is NO FALLBACK. This setting
can be overridden for a particular data table when the table is created
(see “CREATE TABLE” on page 648).
The FALLBACK keyword used alone implies PROTECTION.
NO
DUAL
BEFORE
JOURNAL
the number of before change images to be maintained by default for
each data table created in the new database.
The JOURNAL keyword without NO or DUAL implies single copy
journaling.
If journaling is specified, a DUAL journal is maintained for data tables
with FALLBACK protection.
The JOURNAL keyword without BEFORE implies both types
(BEFORE and AFTER) of images.
SQL Reference: Data Definition Statements
199
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
Syntax Element …
Specifies …
NO
DUAL
LOCAL
NOT LOCAL
AFTER JOURNAL
the type of image to be maintained by default for data tables created in
the new database.
If journaling is specified, a DUAL journal is maintained for data tables
with FALLBACK protection.
NOT LOCAL and LOCAL specify whether single after-image journal
rows for non-fallback data tables are written on the same virtual AMP
(LOCAL) as the changed data rows, or on another virtual AMP in the
cluster (NOT LOCAL). See also “Local Journaling” on page 202.
The JOURNAL keyword without AFTER implies both types
(BEFORE and AFTER) of images.
The default is no journaling.
If only AFTER JOURNAL is specified, then a before change image is
not maintained. If both types are specified, the two specifications
must not conflict.
This setting can be overridden for a particular data table when the
table is created (see “CREATE TABLE” on page 648).
DEFAULT JOURNAL
TABLE =
database_name.table_name
the default table that is to receive the journal images of data tables
created in the new database.
table_name must be defined if journaling is requested, but it need not
reside in the new database.
table_name is automatically created in the new database if
database_name is not specified, or the new database is specified.
If a different database is specified, then that database must exist and
table_name must have been defined as its default journal table.
ANSI Compliance
CREATE DATABASE is a Teradata extension to the ANSI SQL:2003 standard.
CREATE DATABASE is functionally equivalent to the ANSI CREATE SCHEMA statement.
Authorization
The privileges granted to the creator and owner on the new database are WITH GRANT
OPTION.
To create a database, you must have the CREATE DATABASE privilege on the immediate
owner database. The creator and owner receive all the following privileges on the newly
created database:
200
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
•
•
•
•
•
•
•
CHECKPOINT
CREATE DATABASE
CREATE MACRO
CREATE TABLE
CREATE TRIGGER
CREATE USER
CREATE VIEW
•
•
•
•
•
•
•
DELETE
DROP DATABASE
DROP MACRO
DROP PROCEDURE
DROP TABLE
DROP TRIGGER
DROP USER
•
•
•
•
•
•
•
DROP VIEW
DUMP
EXECUTE
INSERT
REVOKE
RESTORE
UPDATE
No privilege is needed to specify a DEFAULT JOURNAL TABLE in a database other than the
database being created. However, when a table is created that specifies a journal, then the user
creating the table must have INSERT privilege on the journal table.
Privileges Granted Automatically
The following privileges are automatically granted to a database when it is created:
•
•
•
•
•
•
•
CHECKPOINT
CREATE AUTHORIZATION
CREATE MACRO
CREATE TABLE
CREATE TRIGGER
CREATE VIEW
DELETE
•
•
•
•
•
•
•
DROP AUTHORIZATION
DROP FUNCTION
DROP MACRO
DROP TABLE
DROP PROCEDURE
DROP TABLE
DROP TRIGGER
•
•
•
•
•
•
DROP VIEW
DUMP
EXECUTE
INSERT
RESTORE
SELECT
The following privileges on itself are not automatically granted to a database when it is
created:
•
•
•
•
•
ALTER EXTERNAL PROCEDURE
ALTER FUNCTION
ALTER PROCEDURE
CREATE DATABASE
CREATE EXTERNAL
PROCEDURE
• CREATE FUNCTION
•
•
•
•
•
•
CREATE PROCEDURE
CREATE USER
DROP DATABASE
DROP USER
EXECUTE FUNCTION
EXECUTE PROCEDURE
Rules for Using CREATE DATABASE
The following rules apply to CREATE DATABASE:
•
The maximum number of databases and users for any one system is 4.2 billion.
•
A database can contain only one journal table. However, any table in a particular database
can use a journal table in a different database.
•
When a database contains a journal table, that journal table shares the PERMANENT
storage capacity of the database with its data tables.
SQL Reference: Data Definition Statements
201
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
•
If necessary, the defined PERM, SPOOL, or TEMPORARY space is changed to the highest
multiple of the number of AMPs on the system less than or equal to the requested space.
•
When a CREATE DATABASE statement is performed, the system places an EXCLUSIVE
lock on the database being created.
•
You can only specify options once.
See Database Administration for more information about space management.
Local Journaling
The LOCAL single AFTER image journal is supported analogously to single BEFORE image
journal: the access privileges required to create or drop LOCAL single AFTER image journal
are the same as for the analogous operation on single BEFORE image journal.
LOCAL single AFTER image journaling is restricted to non-fallback base data tables.
Archive/Recovery rules for LOCAL single AFTER image journal and single BEFORE image
journal are the same, except that LOCAL single AFTER image journal is used with
ROLLFORWARD only, while single BEFORE image journal is used with ROLLBACK only.
MultiLoad, Teradata Parallel Transporter, FastLoad and Archive/Recovery are impacted by the
use of LOCAL journaling.
Also see Database Administration and Database Design.
Activating Permanent Journaling
If you specify only DEFAULT JOURNAL TABLE = table_name, then the system creates a
journal table, but does not activate it.
To activate the permanent journal, you must also specify either the AFTER JOURNAL
journaling option or the BEFORE JOURNAL option or both.
This action causes permanent journaling to be activated for all tables created in this database
afterward. See “Activating Permanent Journaling” on page 78 for information about activating
permanent journaling for existing tables.
To determine which tables in your Teradata Database are journal tables, use the following
query:
SELECT DBC.dbase.databasename (FORMAT 'X(15)'),
DBC.tvm.tvmname (FORMAT 'X(25)')
FROM DBC.tvm, DBC.dbase
WHERE DBC.dbase.databaseid=DBC.tvm.databaseid
AND
DBC.tvm.tablekind='j'
ORDER BY 1,2;
202
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
To determine which databases and users in your Teradata Database currently have a default
journal table defined for them, use the following query:
SELECT d.databasename (TITLE'Database'), TRIM(dx.databasename)
||'.'||TRIM(t.tvmname)(TITLE 'Journal')
FROM DBC.dbase d, DBC.TVM t, DBC.dbase dx
WHERE d.journalid IS NOT NULL
AND
d.journalid <> '00'xb
AND
d.journalid = t.tvmid
AND
t.databaseid = dx.databaseid
ORDER BY 1;
To determine which tables in your Teradata Database are currently being journaled, use the
following query:
SELECT TRIM(Tables_DB)||'.'||TableName (TITLE 'Table',
CHARACTER(26)),'Assigned To' (TITLE ' '),TRIM(journals_db)
||'.'||JournalName (TITLE 'Journals', CHARACTER(26))
FROM DBC.journals
ORDER BY 1,2;
You can also determine which tables in your system are currently being journaled using the
following query that has a somewhat different syntax:
SELECT TRIM(d.databasename)||'.'||TRIM(t.tvmname) (FORMAT
'x(45)',TITLE 'Table'),TRIM(dj.databasename)
||'.'||TRIM(tj.tvmname) (TITLE 'Journal')
FROM DBC.TVM t, DBC.TVM tj, DBC.dbase d, DBC.dbase dj
WHERE t.journalid IS NOT NULL
AND
t.journalid <> '00'xb
AND
t.journalid = tj.tvmid
AND
d.databaseid = t.databaseid
AND
dj.databaseid = tj.databaseid
ORDER BY 1;
Also see “ALTER TABLE” on page 53, “CREATE USER” on page 950, “MODIFY DATABASE”
on page 1071, and “MODIFY USER” on page 1086.
Example 1
The following statement creates a database named personnel from database administration:
CREATE DATABASE personnel FROM administration
AS PERMANENT = 5000000 BYTES, FALLBACK, BEFORE JOURNAL,
DUAL AFTER JOURNAL, DEFAULT JOURNAL TABLE = personnel.fin_copy;
The FALLBACK keyword specifies that for each table created in the personnel database, the
default is to store a secondary, duplicate copy in addition to the primary copy.
The JOURNAL option specifies that the default journaling for each data table is to maintain a
single copy of the before change image and dual copies of the after change image. A duplicate
before change image is maintained automatically for any table in this database that uses both
the fallback and the journal defaults.
The DEFAULT JOURNAL TABLE clause is required because journaling is requested. This
clause specifies that a new journal table named fin_copy is to be created in the new database.
SQL Reference: Data Definition Statements
203
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE DATABASE
Permanent journaling is activated because you specified the BEFORE JOURNAL and AFTER
JOURNAL options. Either option, by itself, is sufficient to activate journaling.
Example 2
To create a new database for the Finance department, use the CREATE DATABASE statement
as follow.
CREATE DATABASE finance FROM sysadmin
AS PERMANENT = 60000000
,SPOOL = 120000000
,FALLBACK PROTECTION
,AFTER JOURNAL
,BEFORE JOURNAL
,DEFAULT JOURNAL TABLE = finance.journals
,ACCOUNT = ’ACCTG’;
The finance database is created from the space available in sysadmin. The 60,000,000 value
represents that many bytes of storage. To create a database, the initiator must have CREATE
DATABASE privileges on the FROM user or database. The new database receives all privileges
that have been granted to the initiator.
In the example, the FROM clause allocates space for finance from the sysadmin space rather
than from user space; therefore, sysadmin is the immediate owner of finance, and marks is not
in the hierarchy of ownership. However, marks is granted automatic creator privileges on
finance, which include the privilege to create other objects in the space owned by finance.
The CREATE DATABASE statement does not include the PASSWORD and STARTUP clauses
or the DEFAULT DATABASE and COLLATION options. Because these clauses and options
affect the session environment, and only a user can establish a session, they do not apply to a
database.
204
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
CREATE ERROR TABLE
Purpose
Defines the name and containing database of a new error table and specifies the name of the
data table with which it is associated.
Syntax
CREATE ERROR TABLE
data_table_name
FOR
error_table_name
database_name.
;
database_name.
1101A436
where:
Syntax element …
Specifies …
database_name
the name of the database in which the error table is to be contained if not in
the current database.
error_table_name
the name of the new error table.
If you do not explicitly specify an error table name, the system generates one
in the form ET_data_table_name, where the characters ET_ are a literal string.
If data_table_name is longer than 27 characters, the system truncates it at the
end and does not return a warning message.
The system returns an error message if the ET_data_table_name default name
duplicates an existing table name. You can then specify an explicit unique
error table name in place of the duplicate error table name.
data_table_name
the name of the data table for which this error table is being created.
The name must correspond to either a permanent base data table or a queue
table; otherwise, the system aborts the request and returns an error message to
the requestor.
ANSI Compliance
CREATE ERROR TABLE FOR is a Teradata extension to the ANSI SQL:2003 standard.
SQL Reference: Data Definition Statements
205
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Authorization
You must have the CREATE TABLE privilege on the database or user in which the error table
is created.
To access an error table that contains UDT columns, you must have at least one of the
following privileges:
•
UDTUSAGE on the specified UDT
•
UDTUSAGE on the SYSUDTLIB database
•
UDTTYPE on the SYSUDTLIB database
•
UDTMETHOD on the SYSUDTLIB database
Privileges Granted Automatically
The creator receives all the following privileges on the newly created error table:
• DELETE
• DROP TABLE
• INSERT
• SELECT
• UPDATE
Rules and Restrictions for Error Tables
Error tables assume the following properties when they are created:
•
You can define only one error table per data table.
A single error table-to-data table relationship has the following advantages:
•
It simplifies error management. Multiple error tables would be more difficult to
manage.
•
It allows the error table to be transparent to users because they do not need to know
the name of the error table for a given data table. You can create or drop an error table
and display its structure indirectly by referencing the data table name in place of the
error table name.
•
You cannot use the ALTER TABLE statement to change any property of an error table.
•
The system maintains the compatibility between data tables and their associated error
tables by disallowing any of the following ALTER TABLE operations when an error table is
defined for a data table:
•
Adding or dropping columns from the data table.
•
Changing the primary index column set of the data table.
Note that you can alter the partitioning of a data table PPI the has an error table.
206
•
Changing the fallback protection of the data table.
•
Any ALTER TABLE request on the error table.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
•
You must create your error tables on base tables, not on views.
The reason for this is the security issue that arises if you create an error table over all the
base table columns in a view. Base table columns that were previously hidden by the view
then become visible to the creator of the error table. The apparent workarounds to this
issue all have problems of their own, which is why creating an error table on a view is not
permitted.
For example:
•
While you could create the error table in a database the LOGGING ERRORS user does
not have access to, that prevents the LOGGING ERRORS user from being able to
perform error recovery.
•
If an error table is created with view columns only, error recovery using error table
rows could become difficult, especially when errors come from a nonview column.
•
You must create an error table before you can log errors against its associated data table.
•
The base data table for which you are creating an error table cannot have more than 2,048
columns.
The newly created error table for this data table adds another 13 error columns to this total
(see “System-Defined Attribute Characteristics and Definitions for Error Table-Specific
Columns” on page 212), bringing the maximum number of columns in an error table to
2,061.
•
If the size of an error table row (data table row plus the 13 ETC_ columns) exceeds the
system row size limit, the CREATE ERROR TABLE request aborts and returns an error
message to the requestor.
•
An error table can be contained in either the same database as its associated data table or in
a different database.
•
Error tables are multiset tables by default to avoid the expense of duplicate row checks.
•
Error tables have the same fallback properties as their associated data table.
•
The system copies the data types of data table columns to the error table.
The system does not copy any other column attributes from the data table to the error
table.
•
Error tables have the same primary index as their associated data table.
Because all error tables are multiset tables by definition, if the primary index for the data
table is defined as a UPI, the system converts its definition to a NUPI for the error table.
•
If the data table associated with an error table has a partitioned primary index, the system
does not copy its partitioning to the error table.
Error tables are always NPPI tables by default and cannot be changed to PPI tables.
See “Partitioned and Nonpartitioned Primary Indexes” on page 718 and Database Design
for information about partitioned primary indexes.
SQL Reference: Data Definition Statements
207
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
•
You cannot define secondary indexes for an error table using the CREATE ERROR TABLE
statement, nor does the system copy secondary indexes defined on the data table to its
error table.
However, you can use the CREATE INDEX statement (see “CREATE INDEX” on
page 336) to add secondary indexes to an existing error table to facilitate scanning its
captured data for analysis (which you cannot do for a MultiLoad error table).
If you do this, then you must drop any of the secondary indexes you have defined on the
error table before you perform an INSERT … SELECT or MERGE operation that specifies
error logging on the data table associated with the error table.
If you do not drop all secondary indexes on an error table, the system returns an error
when you attempt to perform a bulk loading operation into the data table.
•
You cannot define triggers, join indexes, or hash indexes on an error table.
•
Error tables do not handle batch referential integrity violations.
Because batch referential integrity checks are all-or-nothing operations, a batch RI
violation results in the following type of session mode-specific abort and returns an error
message to the requestor:
IF this session mode is in effect …
THEN the erring …
ANSI
request aborts.
Teradata
transaction aborts.
•
The system rejects attempts to insert data rows that cause local target table errors. Such
rows are instead inserted into the error table. Once such errors have been corrected, you
can reload the rows either directly from the error table or from the original source table.
•
As a general rule, the system does not handle error conditions that do not allow useful
recovery information to be logged in the error table.
These errors typically occur during intermediate processing of input data before they are
built into a row format that corresponds to that of the target table.
The system detects such errors before the start of data row inserts and updates. The errors
include the following:
208
•
UDT, UDF, and table function errors
•
Version change sanity check errors
•
Non-existent table sanity check errors
•
Down AMP request against non-fallback table errors
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
•
Data conversion errors.
However, conversion errors that occur during data row inserts and merge updates are
handled as local data errors.
These kinds of errors result in the following type of session mode-specific abort and
returns an error message to the requestor:
IF this session mode is in effect …
THEN the erring …
ANSI
request aborts.
Teradata
transaction aborts.
However, the system does preserve all error table rows logged by the aborted request or
transaction and does not roll them back.
•
In addition to the previously listed errors, the system does not handle the following types
of errors, which result in the following type of session mode-specific abort and returns an
error message to the requestor:
•
Out of PERM or spool space errors
•
Duplicate row errors in Teradata session mode (because the system rejects duplicate
rows silently in Teradata mode)
•
Trigger errors
•
Join Index maintenance errors
•
Identity column errors
•
Implicit-USI violations.
When a table is created with a primary key that is not also the primary index, the
system implicitly defines a USI on that primary key.
A violated implicit USI on a primary key cannot be invalidated because the system
does not allow such a USI to be dropped and then recreated later
These kinds of errors result in the following type of session mode-specific abort and
returns an error message to the requestor:
IF this session mode is in effect …
THEN the erring …
ANSI
request aborts.
Teradata
transaction aborts.
SQL Reference: Data Definition Statements
209
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
•
When an error type that is excluded from logging occurs, such as a USI or referential
integrity error, the system causes the following type of session mode-specific abort and
returns an error message to the requestor:
IF this session mode is in effect …
THEN the erring …
ANSI
request aborts.
Teradata
transaction aborts.
In this case, the system rolls back only the target table rows, and only after the minibatch
load operation has completed in order to collect all error-causing rows. The system
preserves existing error table rows and does not roll them back.
•
You cannot add an error table to a replication group.
•
The system sets other general table properties, such as journaling, checksums, datablock
size, and so on to the defaults applied to CREATE TABLE statements that do not explicitly
specify these settings.
•
You can define an error table for a queue table.
•
You cannot specify the QUEUE attribute when you create that error table.
In other words, while an error table itself cannot be a queue table, a queue table can have
an error table associated with it.
•
You can submit DML requests against a minibatch error table, just as you can for a
MultiLoad error table, and you can make error corrections directly on the data row images
stored in the error table.
After you correct errors in the error table rows, you can then reload the modified rows into
the target table directly from the error table instead of reloading them from the staging
table.
Error Logging Limits
You can specify a WITH LIMIT OF error_limit clause in an INSERT … SELECT or MERGE
request with a value in the range of 1 to 16,000,000, inclusive.7 If you do not specify a WITH
LIMIT OF clause, the request uses the default error limit of 10.
You can also specify a WITH NO LIMIT clause if you do not want to specify an error limit.
If the INSERT … SELECT or MERGE request accumulates the number of errors in the
specified error limit, the request or transaction aborts in ANSI or Teradata mode, respectively,
and all changes to the target table rows are rolled back.
The system preserves any error table rows previously logged by the aborted request or
transaction and does not roll them back.
See “INSERT/INSERT … SELECT” and “MERGE” in SQL Reference: Data Manipulation
Statements for details.
7. This limit is based on the largest number a system semaphore counter can support.
210
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
About Error Tables
Data warehousing environments require increasingly frequent updates of their underlying
databases, and the overall data load strategy must include scheduled incremental loads, or
minibatches, performed throughout the day.
The intent of the LOGGING ERRORS option with INSERT … SELECT and MERGE
minibatches is to complement the FastLoad and MultiLoad batch load utilities that handle
larger volumes of data and more complex loads with multiple target tables or DML
operations, and the continuous load utility, Teradata Parallel Data Pump.
By capitalizing on incremental minibatch loads on a continuous basis using
INSERT … SELECT or MERGE requests or both, you can update your data warehouse as
frequently as is necessary, using a mixture of data loading strategies. Furthermore, such
minibatch requests are not restricted by the inability to load data into tables defined with LOB
columns,8 unique secondary indexes, referential integrity constraints, join indexes, hash
indexes, and triggers that can make bulk data loading into active data warehouse tables a
complicated operation (see Teradata FastLoad Reference and Teradata MultiLoad Reference for
a complete list and description of the Teradata Database data table restrictions they must
observe).
Although Teradata Parallel Data Pump performs minibatch loads, the INSERT … SELECT
and MERGE minibatch options and the Teradata Parallel Data Pump option can serve very
distinct situations. For example, when logged on sessions are near their full capacity, the
INSERT … SELECT or MERGE minibatch options are generally preferable to the Teradata
Parallel Data Pump option. Conversely, when the specific order of updates is important,
Teradata Parallel Data Pump are generally preferable.
The purpose of error tables is to provide a substrate for complex error handling of the
following kinds of minibatch loads:
•
Insert errors that occur during an INSERT … SELECT operation
•
Insert and update errors that occur during a MERGE operation
When an insert or update error occurs on an index or data conversion, the transaction or
request containing the erring statement does not roll back, but instead runs to completion,
logging the rows that caused errors in an error table.
Note that data errors that cause secondary index or referential integrity errors do cause the
transaction or request containing the erring statement to roll back. You must then fix the
errors that caused the secondary index or referential integrity violations before you can again
load those rows into the database.
Error tables are one component of a minibatch system that includes extensions to MERGE
and INSERT … SELECT minibatch load operations to support complex error handling (see
“INSERT/INSERT … SELECT” and “MERGE” in SQL Reference: Data Manipulation
Statements). These DML statement extensions permit you to specify error logging for
INSERT … SELECT and MERGE operations. If you specify error logging, the system logs
error conditions and captures copies of the data rows that cause them in an error table.
8. Note, however, that error logging does not support LOB data. LOBs in a source table are not copied to an
error table; instead, they are represented in the error table as nulls.
SQL Reference: Data Definition Statements
211
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
System-Defined Attribute Characteristics and Definitions for Error
Table-Specific Columns
The following table describes the characteristics of the system-defined and generated error
table-specific columns. The ETC prefix for the column names represents Error Table Column.
Column Name
ETC_DBQL_QID
Data Type and
Attributes
Column Definition
Query ID for the Database Query Log.
The system sets up a time-based query ID to uniquely
identify all error rows for a given request regardless of
whether DBQL is enabled.
DECIMAL(18,0)
NOT NULL
The query ID is incremented for each new request.
ETC_DMLType
A code for the type of DML request that erred, as follows:
Code
D
CHARACTER(1)
Description
Delete operation.
Not currently used.
I
Insert operation.
Indicates either an INSERT … SELECT error or
a MERGE insert error.
U
Update operation.
Indicates either a MERGE update error or a join
UPDATE error.
ETC_ErrorCode
Either a DBC error code or a value of 0.
A row with ETC_ErrorCode = 0 is a special marker row that
confirms the request completed successfully, but logged
one or more errors in a LOGGING ERRORS operation.
INTEGER
NOT NULL
A row with a value for ETC_ErrorCode other than 0
indicates that the request aborted because of the recorded
DBC error code and logged one or more errors in a
LOGGING ERRORS operation.
The system does not write a marker row for a request that
completes successfully without logging any errors.
212
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Column Name
ETC_ErrSeq
Column Definition
Error sequence number.
The value provides a numeric sequence that is easier to
refer to for error analysis and recovery purposes than the
timestamp values in ETC_TimeStamp.
Data Type and
Attributes
INTEGER
NOT NULL
The value stored for ETC_ErrSeq begins the sequence with
1 for the first error of a given request, and increments by 1
for each subsequent error recorded.
The ETC_ErrSeq value does not reflect the true processing
sequence of index rows that cause USI or referential
integrity errors because, for example, the system assigns
the sequence numbers for referential integrity errors when
it informs the AMPs that own the data rows of the index
violations, not when it first detects those violations.
ETC_IndexNumber
SQL Reference: Data Definition Statements
Contains either the ID for the index that caused a USI or
referential integrity violation or is set null.
SMALLINT
213
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Column Name
ETC_IdxErrType
Data Type and
Attributes
Column Definition
Indicates if the index ID stored in ETC_IndexNumber
refers to an USI violation or a referential integrity
violation.
Code
null
CHARACTER(1)
NOT
CASESPECIFIC
Description
ETC_IndexNumber is null.
r
Referential integrity violation (parent-delete
case).
R
Referential integrity violation (child-insert
type).
U
Unique secondary index violation.
Because ETC_IdxErrType is defined with the NOT
CASESPECIFIC attribute, both child and parent
referential integrity violations are selected when you
specify a predicate condition of WHERE
ETC_IdxErrType = 'R'.
To work around this problem, make your predicate
conditions case specific, as follows:
To select only
these errors …
Specify this condition …
child-insert
WHERE etc_idxerrtype (CS)
= 'R'
parent-delete
WHERE etc_idxerrtype (CS)
= 'r'
This provides a simple and reliable check for child versus
parent referential integrity errors, and for parent versus
child tables identified by ETC_RITableId.
214
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Column Name
ETC_RowId
Column Definition
Records the rowIDs or row key values specified in the
following table for the listed error conditions.
IF …
THEN the system logs this …
the insert row is a
duplicate of an
existing row in the
target table
rowID of the target table row.
the insert row fails a
CHECK constraint
the row key of the insert row
with 0s in its uniqueness
portion.
an insert row build
fails because an
internal error such as
a divide by zero error
the row key of the insert row
with 0s in its uniqueness
portion.
the update row of a
MERGE request is a
duplicate of an
existing row in the
target table
rowID of the original image of
the target table row being
updated.
the update row fails a
CHECK constraint
rowID of the original image of
the target table row being
updated.
an update row build
for a MERGE request
fails because of an
internal error such as
a divide by zero error
rowID of the target table row
being updated.
multiple source rows
of a MERGE request
are attempting to
update the same target
table rowa
rowID of the target table row.
anything else
null.
Data Type and
Attributes
BYTE(10)
This information is intended for the use of Teradata
support personnel and is probably not useful for end users.
ETC_TableId
SQL Reference: Data Definition Statements
Identifies the table associated with the value stored in
ETC_FieldId.
BYTE(6)
215
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Column Name
ETC_FieldId
Data Type and
Attributes
Column Definition
Stores the id of the column that caused an error condition,
which is the field ID stored in DBC.TVFields.
FOR this error
type …
Indicates …
• composite
key
• index
violation
the column ID of the first column in
the composite key or index.
• column
violation
• constraint
violation
the column ID of the column
returned by the system for a
constraint violation.
duplicate row
null.
SMALLINT
If a table constraint contains two columns, the system
stores the ID of the column on the right-hand side of the
constraint expression.
For example, a CHECK (y>x) error captures the fieldiD
of column x.
ETC_RITableId
216
Identifies the other table involved in an referential integrity
violation.
FOR this error
type …
Identifies this RI table …
child-insert
referenced parent.
parent-delete
referencing child.
BYTE(6)
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Column Name
ETC_RIFieldId
Column Definition
Identifies the column in the table associated with an RI
violation.
FOR this table
type …
Identifies the …
parent
missing UPI or USI column
referenced by an inserted child row.
child
foreign key column that referenced
the UPI or USI key in a deleted
parent row.
Data Type and
Attributes
SMALLINT
For composite keys, ETC_RIFieldId identifies only the first
column defined for the key, which is often enough
information to identify the key uniquely.
ETC_TimeStamp
Indicates the time the system detects an error, not the time
the system writes the error row to the error table.
TIMESTAMP(2)
NOT NULL
ETC_Blob
Not currently used.
BLOB
This column consumes space in the retrieval of rows from
an error table.
If an error table has a large number of data table columns,
the inclusion of this column in the select list might cause
the query to reach an internal Teradata database limitation
and return a 'Row size or Sort Key size
overflow' error.
If this happens, drop the ETC_Blob column from the select
list.
The size limit for ETC_Blob is 2 MBytes, which is large
enough to store a maximum-sized memory segment
associated with the step that produces a data conversion
error.
a. This is not permitted by the ANSI SQL:2003 standard.
SQL Reference: Data Definition Statements
217
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Error Table Row Size Minimization
To minimize the size of error table rows, the system stores only the IDs of fields and users, not
their names. To determine the names associated with the stored field IDs and user IDs, you
can run queries against the DBC.Tables3VX view.
For example:
SELECT TableName, FieldName, ETC_ErrorCode
FROM DBC.Tables3VX, ET_myerrtbl
WHERE TableId = ETC_TableId
AND
FieldId = ETC_FieldId
AND
ETC_DBQL_QID = 385520516506583068;
where:
Request element …
Specifies …
ET_myerrtbl
the default system-generated name of the error table for base table myerrtbl,
for which you want to retrieve table and column names.
385520516506583068
the unique DBQL query ID for this request.
See Teradata Parallel Data Pump Reference, Teradata FastLoad Reference, and Teradata
MultiLoad Reference for the definitions of the error tables generated by those bulk loading
utilities.
Dictionary Support for Error Tables
The system provides one dictionary table, DBC.ErrorTbls, and three views, DBC.ErrorTblsV,
DBC.ErrorTblsVX, and DBC.Tables3VX, to support error tables.
DBC.ErrorTbls maintains the relationships between error tables and their data tables rather
than the table header.
You can query the DBC.ErrorTblsV and DBC.ErrorTblsVX views to report error table names
and their associated data table and database names.
You can query the DBC.Tables3VX view to report the database, table, and column names
associated with the table IDs and column IDs stored in error table rows.
See Data Dictionary for the definitions and usage details about DBC.ErrorTbls,
DBC.ErrorTblsV, DBC.ErrorTblsVX, and DBC.Tables3VX. The topic “Error Table Row Size
Minimization” on page 218 also provides an example of how to use the DBC.Tables3VX view.
218
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Usage Considerations for the Error Table Columns
The following table supplies additional usage considerations for Error Table information
beyond that listed in “System-Defined Attribute Characteristics and Definitions for Error
Table-Specific Columns” on page 212.
Column
ETC_DBQL_QID
Usage Notes
The system sets up a time-based query ID regardless of whether DBQL is
enabled, and increments it for each new request.
You can use the column ETC_DBQL_QID to uniquely identify all error
rows for a request.
The latter is less reliable because in a restart, the session numbers begin
incrementing from the same base value. As a result, two different requests
might have the same host, session, and request numbers if there are restarts.
ETC_ErrSeq
You can use ETC_ErrSeq column to determine the order of row updates and
inserts for a MERGE operation.
ETC_ErrSeq provides a numeric sequencing that is easier to refer to for
error analysis and recovery purposes than the timestamps in
ETC_TimeStamp.
If the data row size plus the fixed error table columns exceeds the system row size limit, an
ANSI session mode request aborts and returns an error message to the requestor, while a
Teradata session mode transaction containing the erring CREATE ERROR TABLE request
aborts and returns an error message to the requestor.
Using Error Table Data to Isolate Problems
Use the following general procedure to isolate problems using error table data:
1
Query the error table to retrieve information on the errors logged for a user in an error
table named ET_t and the DBQL query ID returned in the error or warning message:
SELECT ETC_ErrorCode, FieldName, ETC_IndexNumber, ETC_IdxErrType
FROM ET_t, DBC.Tables3VX
WHERE ETC_DBQL_QID = 123456789012345678
AND
ETC_TableID = TableID;
2
Look at each error code and column value related to the error and determine if any action
needs to be taken.
3
End of procedure.
The following error table columns are more useful for troubleshooting by Teradata support
personnel than for end users:
•
ETC_RowId
•
ETC_ErrSeq
SQL Reference: Data Definition Statements
219
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Handling Logged Reference Index and Unique Secondary Index Errors
If any Reference Index or USI errors are logged during an INSERT … SELECT or MERGE
operation, delete the data rows that caused the index violations from the source (staging) table
and rerun the load request.
Archive/Recovery Utility Support for Error Tables
The following points apply to Archive/Recovery utility support for error tables:
•
An all-AMPs or dictionary archive includes all rows in DBC.ErrorTbls.
Error tables are archived only if they are contained by the database being archived.
•
When a database containing an error table is restored from either a cluster or all-AMPs
archive, the corresponding row in DBC.ErrorTbls for the error table is also restored.
•
Table-level archives do not include DBC.ErrorTbls rows.
•
An archived table can be restored only if it has not been dropped. You cannot restore a
dropped error table.
•
If an error table has not been dropped, it is represented by a row in DBC.ErrorTbls, so
restoring it from an archive does not require its DBC.ErrorTbls row to be restored as well.
•
Using the Archive utility COPY command to copy an error table does not restore its
associated DBC.ErrorTbls row.
•
An error table copied using the Archive utility COPY command becomes a regular data
table on the target system.
See Teradata Archive/Recovery Utility Reference for details about the COPY command.
Example 1
The following example creates an error table with a default name of et_t for data table t.
CREATE ERROR TABLE FOR t;
Example 2
The following example creates an error table named e for data table t.
CREATE ERROR TABLE e FOR t;
220
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ERROR TABLE
Related Topics
For further information about error tables, see the following topics and manuals:
•
“ALTER TABLE” on page 53
•
“CREATE TABLE” on page 648
•
“CREATE TABLE (Queue Table Form)” on page 817
•
“DELETE DATABASE/ DELETE USER” on page 997
•
“DROP ERROR TABLE” on page 1011
•
“DROP MACRO/ DROP PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP VIEW”
on page 1027
•
“HELP ERROR TABLE” on page 1461
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
•
“INSERT/INSERT … SELECT” in SQL Reference: Data Manipulation Statements
•
“MERGE” in SQL Reference: Data Manipulation Statements
•
Teradata Archive/Recovery Utility Reference
•
Teradata FastLoad Reference
•
Teradata MultiLoad Reference
•
Teradata Parallel Data Pump Reference
•
Maurice Ho, Teradata 12.0 SQL Bulk Loading Complex Error Handling User's Guide,
Teradata Database Orange Book 541-0006649, 2007.
SQL Reference: Data Definition Statements
221
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
CREATE FUNCTION/
REPLACE FUNCTION
Purpose
Compiles and installs a UDF and creates the SQL function definition used to invoke that UDF.
Syntax
CREATE
function_name
FUNCTION
A
database_name.
REPLACE
,
A
(
)
B
parameter
data type
parameter_name
B
return
data type
RETURNS
C
external routine
data type
CAST FROM
C
language_clause
SQL_data_access
SQL_data_access
language_clause
D
specific_function_name
SPECIFIC
database_name.
CLASS
AGGREGATE
AG
PARAMETER STYLE
(
interim_size
)
SQL
TD_GENERAL
DETERMINISTIC
NOT
CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
specific_function_name
SPECIFIC
database_name.
CLASS
language_clause
SQL_data_access
SQL_data_access
language_clause
AGGREGATE
AG
(
PARAMETER STYLE
interim_size
)
SQL
TD_GENERAL
DETERMINISTIC
NOT
CALLED ON NULL INPUT
RETURNS NULL ON NULL INPUT
D
E
EXTERNAL
NAME
external_function_name
'
F
D
S
C
delimiter
delimiter
function_entry_name
'
I delimiter name_on_server delimiter include_name
L delimiter library_name
O delimiter name_on_server delimiter object_name
P delimiter package_name
S delimiter name_on_server delimiter source_name
E
PARAMETER STYLE
SQL
TD_GENERAL
EXTERNAL SECURITY
authorization_name
INVOKER
222
;
DEFINER
1101A323
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Parameter, Return, and External Function Data Types
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
(fractional_seconds_precision)
WITH TIMEZONE
TIMESTAMP
(fractional_seconds_precision)
WITH TIMEZONE
INTERVAL YEAR
(precision)
TO MONTH
INTERVAL MONTH
(precision)
INTERVAL DAY
TO
(precision)
HOUR
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL HOUR
TO
(precision)
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL MINUTE
(precision)
TO SECOND
(- fractional_seconds_precision - )
INTERVAL SECOND
(precision
)
,fractional_seconds_precision
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
BINARY LARGE OBJECT
(
integer
AS LOCATOR
(
G
K
M
BLOB
UDT_name
SYSUDTLIB.
CHAR
BYTE
( integer )
CHARACTER SET
GRAPHIC
VARCHAR
server_character_set
( integer )
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
CHARACTER LARGE OBJECT
CLOB
SQL Reference: Data Definition Statements
( integer
( AS LOCATOR
G
K
M
1101D014
223
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
where:
Syntax element …
Specifies …
database_name
an optional database name specified if the function is to be created
or replaced in a non-default database.
If you use the recommended SYSLIB database as your UDF
depository (see “Function Calling Argument” on page 246), you
must modify the size of its permanent space and grant appropriate
access rights on it because it is created with 0 permanent space and
without access privileges.
Users must have the EXECUTE FUNCTION privilege on any UDF
they run from SYSLIB.
A UDF used as a cast, ordering, or transform routine for a UDT
must be created in the SYSUDTLIB database.
If you do not specify a database name, then the system creates or
replaces the function within the current database.
function_name
the calling name for the function.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the function name as short as possible (see
“Maximum Size of Teradata UNIX MP-RAS Command Line
Argument Affects Names and Number of External Routines in a
Database” on page 238).
You cannot give a UDF the same name as an existing Teradata
Database-supplied function (also known as an intrinsic function)
unless you enclose the name in double quotation marks. For
example, “TRIM”(). Using the names of intrinsic functions for
UDFs is a poor programming practice and should be avoided. See
the topic on naming conventions for details about avoiding other
naming conflicts with methods and UDTs.
function_name must match the spelling and case of the C or C++
function name exactly if you do not specify a specific_function_name
or external_function_name. This applies only to the definition of the
function, not to its use.
SQL supports function name overloading within the same function
class (see “CLASS function_class” on page 227), so function_name
need not be unique within its class; however, you cannot give the
same name to both a scalar and an aggregate function within the
same database.
Parameter data types and number of parameters are used to
distinguish among different functions within the same class that
have the same function_name.
See SQL Reference: UDF, UDM, and External Stored Procedure
Programming for further information about function overloading.
224
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
function_name (continued)
See the following sections for further information:
•
•
•
•
•
[parameter_name]
parameter_data_type
[locator_indication]
“Function Identifiers” on page 244
“Function Name” on page 245
“Function Calling Argument” on page 246
“Function Name Overloading” on page 247
“Parameter Names and Data Types” on page 249
a parenthetical comma-separated list of data types, including UDTs,
and optional parameter names and locators for the variables to be
passed to the function.
Parameter names must be unique within a UDF definition.
You cannot use the keyword SELF to name UDF parameters.
The maximum number of parameters a UDF accepts is 128.
BLOB and CLOB types must be represented by a locator (see SQL
Reference: Data Manipulation Statements for a description of
locators). The Teradata Database does not support in-memory LOB
parameters: an AS LOCATOR phrase must be specified for each LOB
parameter and return value.
Note, however, that whenever a LOB that requires data type
conversion is passed to a UDF, the LOB must be materialized for the
conversion to take place.
You must specify opening and closing parentheses even if no
parameters are to be passed to the function.
If you specify one parameter name, then you must specify names for
all the parameters passed to the function.
If you do not specify parameter names, the system assigns unique
names to them in the form P1, P2, …, Pn. These names are used in
the COMMENT statement (see “COMMENT (Comment Placing
Form)” on page 166) and displayed in the report produced by the
HELP FUNCTION statement (see “HELP FUNCTION” on
page 1464), and appear in the text of error messages.
The data type associated with each parameter is the type of the
parameter or returned value. All Teradata Database data types are
valid. Distinct and structured UDTs are valid for scalar UDFs only.
Character data can also specify a CHARACTER SET clause.
For data types that take a length or size specification, like BYTE,
CHARACTER, DECIMAL, VARCHAR, and so on, the size of the
parameter indicates the largest number of bytes that can be passed
(see “Parameter Names and Data Types” on page 249).
SQL Reference: Data Definition Statements
225
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
RETURNS return_data_type
the data type for the value returned by the external function.
Distinct and structured UDTs are valid for scalar UDFs only.
The function is responsible for providing the returned data with the
correct type. If the return type is difficult for the function to create,
you should also specify a CAST FROM clause so the system can
perform the appropriate data type conversion (see SQL Reference:
Functions and Operators for more information about using CAST
expressions).
The result type has a dictionary entry in DBC.TVFields under the
name RETURN0[n], where n is a sequence of digits appended to
RETURN0 rows to make each value unique, ensuring that no
user-defined parameter names are duplicated. The value of n is
incremented until it no longer duplicates a parameter name.
The n subscript is not used if there is no parameter name of
RETURN0.
See “Returns Clause” on page 250.
CAST FROM
exernal_function_data_type
the result type returned by the external function that is to be
converted to the type specified by the RETURNS clause.
Example:
...RETURNS DECIMAL(9,5) CAST FROM FLOAT...
Whenever a LOB that requires data type conversion is passed to a
UDF, the LOB must first be materialized for the conversion to take
place.
The value for external_function_data_type can be a UDT.
language_clause
a code that represents the programming language in which the
external function is written.
The valid languages for writing UDFs are C and C++.
IF the UDF is written in this
language …
THEN the code for
language_clause is …
C
C
C++
CPP
This must be specified as LANGUAGE C or LANGUAGE CPP even
if the external function is supplied in object form.
If the external function object is not written in C or C++, it must be
compatible with C or C++ object code.
This clause is mandatory.
See “Language Clause” on page 250.
226
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
SQL_data_access
whether the external function body accesses the database or contains
SQL statements
This must be specified as NO SQL.
This clause is mandatory.
See “SQL Data Access Clause” on page 251.
SPECIFIC [database_name.]
specific_function_name
the specific name for the function.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the specific function name as short as
possible (see “Maximum Size of Teradata UNIX MP-RAS Command
Line Argument Affects Names and Number of External Routines in a
Database” on page 238).
Unlike function_name (see “function_name (continued)” on
page 225), specific_function_name must be unique within the
database. This name is stored in DBC.TVM as the name of the UDF
database object (see “Function Identifiers” on page 244 and
“External Body Reference Clause” on page 255).
This clause is mandatory for overloaded function_names, but
otherwise optional and can only be specified once per function
definition.
See “Specific Function Name Clause” on page 251.
CLASS function_class
the class of the function being defined.
Specify this keyword …
For this function class …
none
scalar.
AGGREGATE
aggregate.
Do not specify this clause for scalar functions.
This clause is optional and can only be specified once per function
definition.
See “Function Class Clause” on page 251.
interim_size
the size of the aggregate cache allocated for an aggregate UDF.
The minimum value is 1 byte.
The maximum value is 64,000 bytes.
The default value is 64 bytes.
See “Optimizing the Aggregate Cache” on page 252.
SQL Reference: Data Definition Statements
227
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
PARAMETER STYLE
the parameter passing convention to be used when passing
parameters to the function.
The specified parameter style must match the parameter passing
convention of the external function.
Style
SQL
Description
Uses indicator variables to pass arguments.
As a result, you can always pass nulls as
inputs and return them in results.
TD_GENERAL
Uses parameters to pass arguments.
Can neither be passed nulls nor return nulls.
If you do not specify a parameter style at this point, you can specify
one with the external body reference.
You cannot specify parameter styles more than once in the same
CREATE/REPLACE FUNCTION statement.
The default is SQL.
This clause is optional and can only be specified once per function
definition.
See “Parameter Style Clause” on page 253 for more information on
parameter styles.
[NOT] DETERMINISTIC
whether the function returns identical results for identical inputs.
For example, if the function calls a random number generator as
part of its processing, then the results of a function call cannot be
known in advance of making the call and the function is NOT
DETERMINISTIC.
The default is NOT DETERMINISTIC.
This clause is optional and can only be specified once per function
definition.
See “Deterministic Characteristics Clause” on page 254.
RETURNS NULL ON
NULL INPUT
that if any parameters are null at the time the function is to be called,
a null result is returned without evaluating the function.
You cannot specify this option for aggregate functions.
This clause is optional and can only be specified once per function
definition.
The default is CALLED ON NULL INPUT.
See “Null Call Clause” on page 254.
228
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
CALLED ON NULL INPUT
that the function is always evaluated whether parameters are null at
the time the function is to be called or not.
If the PARAMETER STYLE for the function is TD_GENERAL, nulls
generate an exception condition.
This clause is optional and can only be specified once per function
definition.
The default is CALLED ON NULL INPUT.
See “Null Call Clause” on page 254.
EXTERNAL
the introduction to the mandatory external function body reference
clause.
This clause can specify 3 different things:
• The keyword EXTERNAL only.
• The keywords EXTERNAL NAME plus an external function
name (with optional Parameter Style specification)
• The keywords EXTERNAL NAME plus a set of external string
literals.
See “External Body Reference Clause” on page 255.
NAME
external_function_name
the entry point for the function object.
Case is significant and must match the C or C++ function name.
See “External Name Clause” on page 257.
NAME
external_string_literal
a string that specifies the source and object components needed to
build the function and, optionally, whether to compile the UDF C or
C++ object code with debug symbols.
Depending on the initial code in the sequence, the string specifies
either the C/C++ function object name for the UDF or an encoded
name or path for the components needed to create the function.
SQL Reference: Data Definition Statements
229
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
NAME
external_string_literal
The following table briefly documents the codes used to specify
component locations:
(continued)
IF you specify this
code …
F
THEN the …
string that follows is the entry point name of
the C or C++ function object.
See “Function Entry Name Clause” on
page 260.
C
source or object code for the function is
stored on the client and the string that
follows is the path to its location.
See “Client-Server UDF Code Specification”
on page 260.
S
source or object code for the function is
stored on the server and the string that
follows is the path to its location.
See “Client-Server UDF Code Specification”
on page 260.
The following table briefly documents the path specifications for the
external function. The character ¡ represents an arbitrary
user-defined delimiter.
You must use the same delimiter throughout the string specification.
File Type
Function object
Syntax
F¡function_entry_point_name
See “Function Entry Name Clause” on
page 260 for details.
Include
I¡name_on_server¡include_name
See “Include Name Clause” on
page 261 for details.
230
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
NAME
external_string_literal
(continued)
File Type
Library
Syntax
L¡library_name
See “Library Name Clause” on
page 262 for details.
Object
O¡name_on_server¡object_name
See “Object File Name Clause” on
page 262 for details.
Package
P¡package_name
See “Package Name Clause” on
page 263 for details.
Source
S¡name_on_server¡source_name
See “Source File Name Clause” on
page 265 for details.
To compile the C or C++ object code with debug symbols for core
dump analysis, specify the delimited character D at any point in the
external string literal. This feature does not produce a useful .so or
.dll file with debug symbols for Linux and Windows systems.
IF you …
THEN the system compiles the UDF
source code …
specify the D option
and produces debug symbols.
Generates a core file when a protected
mode UDF crashes.
do not specify the D
option
but does not generate debug symbols.
The purpose of the D option is to provide debug symbol
information for the UDF when examining a UDF core file with gdb
(see SQL Reference: UDF, UDM, and External Stored Procedure
Programming).
See the user documentation for your C or C++ compiler and
debugger for debugging information.
A side effect of specifying the D option is that linked libraries
become larger because they must also contain all the symbol
information.
SQL Reference: Data Definition Statements
231
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Syntax element …
Specifies …
EXTERNAL SECURITY
keywords introducing the external security clause.
This clause is recommended for UDFs that perform operating
system I/O operations because it permits you to specify a particular
OS user under whom the function runs. Otherwise, a protected
mode UDF runs under the generic user tdatuser.
See “When to Specify Unprotected Mode” on page 22,
“Authorization Rules” on page 178, and “Protected and Unprotected
Execution Modes” on page 240 for additional information.
Also see “CREATE AUTHORIZATION/ REPLACE
AUTHORIZATION” on page 174.
DEFINER
that the UDF runs in the client user context of the associated
security authorization object created for this purpose, which is
contained within the same database as the function.
IF you …
THEN …
specify an
authorization name
an authorization object with that name
must be defined before you can run the
function.
do not specify an
authorization name
you must define a default DEFINER
authorization object.
The default authorization object must
be defined before a user can run the
function.
The system reports a warning if the specified authorization name
does not exist at the time the UDF is created, stating that no
authorization name exists.
If you then attempt to execute the function, the statement aborts and
the system returns an error to the requestor.
authorization_name
an optional identifier for this DEFINER.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174.
INVOKER
that the function runs using the INVOKER authorization associated
with the logged on user who is running the function.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174.
PARAMETER STYLE
See “PARAMETER STYLE” on page 228.
If you do not specify a parameter style at this point, you can specify
one after you specify a language clause and an SQL data access
clause.
You cannot specify parameter styles more than once in the same
CREATE/REPLACE FUNCTION statement.
232
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
ANSI Compliance
CREATE FUNCTION is ANSI SQL:2003-compliant with extensions.
REPLACE FUNCTION is a Teradata extension to the ANSI SQL-2003 standard.
Authorization
The privileges required to perform CREATE FUNCTION and REPLACE FUNCTION are
different.
•
You must have explicit CREATE FUNCTION privileges on the database, including
SYSUDTLIB for UDFs associated with UDTs, in which the function is to be contained to
perform the CREATE FUNCTION statement.
The system does not grant the CREATE FUNCTION privilege automatically when you
create a database or user: you must grant that privilege explicitly.
CREATE FUNCTION is not granted implicitly on the databases and functions owned by a
database or user unless the owner also has an explicit WITH GRANT OPTION privilege
defined for itself.
•
You must have explicit DROP FUNCTION privileges on the function or on the database in
which the function is contained to perform the REPLACE FUNCTION statement on an
existing function. You do not need the CREATE FUNCTION privilege to replace a
function.
•
You must have explicit CREATE FUNCTION privileges on the database in which the
function is to be contained to perform the REPLACE FUNCTION statement to create a
new function.
If a UDT is specified as an input parameter or the function result, the current user must have
one of the following privileges:
•
UDTUSAGE on the SYSUDTLIB database.
•
UDTUSAGE on the specified UDT.
Privileges Granted Automatically
The following privileges are granted automatically to the creator of a function:
•
DROP FUNCTION
•
EXECUTE FUNCTION
Downloadable UDF Samples
You can find downloadable samples of UDFs at the Tech Center site at Teradata.com. The full
URL is as follows: http://www.teradata.com/t/page/118769/index.html.
SQL Reference: Data Definition Statements
233
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Relationship Among UDFs, Table UDFs, UDMs, and External Stored
Procedures.
UDFs, table UDFs, methods, and external stored procedures are specific variations of one
another and share most properties in common. The generic term used to describe all these is
external routine. See “CREATE FUNCTION (Table Form)” on page 279, “CREATE
METHOD” on page 431, “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463, and “REPLACE METHOD” on page 1112.
Naming Conventions: Avoiding Name Clashes Among UDFs, UDMs, and
UDTs
For UDF, UDM, and UDT names not to clash, they must observe the following two rules:
•
The following column pair must be unique within the DBC.TVM table:
•
•
DatabaseID, TVMNameI
The signature of the following routine must be unique:
•
database_name.routine_name(parameter_list).
UDFs, UDMs, and UDTs can have the same SQL names as long as their SPECIFIC names and
associated routine signatures are different.9
The value of database_name is always SYSUDTLIB for UDFs associated with UDTs, including
UDFs used to implement the following functionality on behalf of a UDT:
•
Casts
•
Orderings
•
Transforms
This means that the Database ID column entry is always the same. Because of this, name
uniqueness is dependent on the TVMNameI column value only.
The following list highlights the algorithm used to determine the TVMNameI entry for UDTs
and UDMs named using the Latin character set. Note that all names entered into TVMNameI
have been converted to all capital letters. The TVMNameI entry is always assumed to be 30
bytes long.
•
UDTs created by a CREATE TYPE statement have a SPECIFIC name of at most 30
characters. This name is system-generated based on the specified UDT name.
The system generates the SPECIFIC name by truncating any UDT names that exceed 30
characters to a length of 30 characters.
9. In the case of UDTs, the SPECIFIC name reference is to the SPECIFIC names of any method signatures
within a UDT definition, not to the UDT itself, which does not have a SPECIFIC name.
234
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
•
Every time you submit a CREATE TYPE statement, the system automatically generates a
UDF on its behalf to obtain a UDT instance.
This UDF has a TVMNameI column entry constructed as shown by the following process:
a
A specific name of at most 28 characters is generated based on the UDT name.
The specific name is generated as the concatenation of at most the first 20 characters
from the UDT name and the last 8 HEXADECIMAL digits of the system-assigned
routine identifier for the system-generated UDF.
b
The character sequence _C is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
Observer methods, auto-generated on behalf of structured type attributes, have a
TVMNameI column entry constructed as shown by the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
attribute names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the attribute name.
iv A LOW LINE (underscore) character.
v
b
The last 8 HEXADECIMAL digits of the routine identifier assigned to the observer
instance method.
The character sequence _O is appended after the characters generated by Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
Mutator methods, auto-generated on behalf of structured type attributes, have a
TVMNameI entry constructed as shown by the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
attribute names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated.
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the attribute name.
iv A LOW LINE (underscore) character.
v
The last 8 HEXADECIMAL digits of the routine identifier assigned to the mutator
instance method.
SQL Reference: Data Definition Statements
235
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
b
The character sequence _M is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
The system adds the SPECIFIC method names of instance methods created by a CREATE
TYPE, ALTER TYPE, or CREATE METHOD statement to the TVMNameI column in
DBC.TVM.
If the coder of a method does not specify a SPECIFIC method name, then the system
generates one for it with the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
instance method names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the instance method name.
iv A LOW LINE (underscore) character.
v
•
The last 8 HEXADECIMAL digits of the routine identifier assigned to the instance
method.
b
The character sequence _R is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
End of process.
The system adds the SPECIFIC method names of constructor methods created by a
CREATE TYPE, ALTER TYPE, or CREATE METHOD statement to the TVMNameI
column in DBC.TVM.
If the coder of a method does not specify a SPECIFIC method name, then the system
generates one for it with the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
constructor method names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the constructor method name.
iv A LOW LINE (underscore) character.
v
236
The last 8 HEXADECIMAL digits of the routine identifier assigned to the
constructor method.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
b
The character sequence _C is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
End of process.
The SPECIFIC name of a UDT, UDM or UDF must be unique to avoid name clashes.
FOR this type of external routine …
The SPECIFIC name is …
UDT
always its UDT name.
• UDM
• UDF
user-defined.
There are two exceptions to this rule for structured types:
• System-generated observer methods.
• System-generated mutator methods.
The SPECIFIC names for these are always the same as the
names of the structured UDT attributes on which they operate.
Note that for UDMs, the SPECIFIC name is defined in its
signature within its associated UDT, not within the CREATE
METHOD statement.
Similarly, the signatures of external routines must be unique. The following rules apply:
•
For every UDT you create, the system generates a UDF with the following signature:
SYSUDTLIB.UDT_Name().
No other UDF can have this signature.
•
When you create a UDM, the system treats it as a UDF for which the data type of its first
argument is the same as the UDT on which that UDM is defined.
For example, a UDM named area(), defined on the UDT named circle, would have the
signature SYSUDTLIB.area(circle). It follows that there can be no other UDF with this
same signature.
Given the single database (SYSUDTLIB) Teradata UDT environment, the following rules
apply:
•
A UDT and a SYSUDTLIB UDF with no parameters cannot have the same name.
•
A method for a structured UDT cannot have the same name as any of the attributes for
that type if the signature of the method and the signature of either the observer or mutator
methods for the attribute match.
You must define a transform group for each UDT you create. Because the system creates a
transform group for you automatically when you create a distinct UDT, you cannot create an
additional explicit transform group without first dropping the system-generated transform.
The names of UDT transform groups need not be unique, so you can use the same name for
all transform groups if you wanted to.
Unlike the names for UDTs, UDMs, and UDFs, the names of transform groups are stored in
DBC.UDTTransform rather than DBC.TVM.
SQL Reference: Data Definition Statements
237
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Maximum Size of Teradata UNIX MP-RAS Command Line Argument Affects
Names and Number of External Routines in a Database
All of the UDFs, UDMs, and external stored procedures, collectively called external routines, in
a given database are linked into a single dynamic linked library (.so file on Teradata UNIX
MP-RAS).
Whenever you create a new external routine or UDT, the system uses the make utility on the
server to compile the source code and relink the .so file with the new object file and all the
other existing object files.
On a Teradata UNIX MP-RAS system, the command line argument the system passes to the
make utility to relink the .so file can exceed the maximum command line argument size if you
have many external routines in the database or if their names are long. When this happens, the
system returns an "Arg list too long" error.10
For example, suppose you create a new distinct UDT in the SYSUDTLIB database:
CREATE TYPE really_long_name_for_a_UDT AS INTEGER FINAL;
The system automatically generates functions and methods for the UDT. The output you see
looks something like this:
/usr/bin/cc -Xc -I /tpasw/etc -c -o REALLY_LONG_NAME_FOR_A_UDT_C.o
REALLY_LONG_NAME_FOR_A_UDT_C.cpp
Teradata High Performance C/C++ Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ef_26.so
REALLY_LONG_NAME_FOR_A_UDT_C.o @FileList -ludf -lumm2 -lmw -lm -lcc
If the command line argument that the system passes to the make utility exceeds the
maximum command line argument size, the system returns the following error message:
Error: Arg list too long
(/usr/bin/cc:) Exec of /usr/ccs/bin/ld failed
To work around this limitation, you can do any of the following:
•
Drop all unnecessary UDTs and external routines from the database.
•
Rename UDTs and external routines to shorter names.
•
Change the ARG_MAX kernel parameter to the maximum value, rebuild the kernel, and
reboot the system.
ARG_MAX is an Teradata UNIX MP-RAS system tuning parameter located in the stune
file. This parameter determines the maximum buffer size for passing an argument to a
command line process.
The mtune file documents the minimum, maximum, and current values of ARG_MAX. If
this entry does not exist in stune, the DBA must add it. After changing the ARG_MAX
value, the DBA must do an idbuild to rebuild the kernel and then reboot UNIX. It may be
necessary to perform this procedure on every node of an MPP system.
10. This restriction applies only to Teradata MP-RAS systems. It does not apply to Windows and Linux
systems.
238
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Note: These workarounds may not work in all cases. For example, if you reach the maximum
number of UDTs allowed on a system, the only solution is to drop enough UDTs to stay within
the system maximum for ARG_MAX.
Usage Restrictions for User-Defined Functions
UDF usage is restricted as follows:
•
You cannot perform a CREATE FUNCTION or REPLACE FUNCTION request from an
embedded SQL application.
•
A UDF cannot reference a recursive view.
•
Scalar UDFs can specify both distinct and structured UDTs as input and return
parameters.
Aggregate UDFs cannot specify either distinct or structured UDTs as input or return
parameters.
•
If you specify a UDT as either an input parameter or as the function result, the current
user of the function must have either the UDTUSAGE privilege on the SYSUDTLIB
database or the UDTUSAGE privilege on the specified UDT.
•
UDFs that are used as cast routines, ordering routines, or transform routines must be
contained within the SYSUDTLIB database.
Restrictions On The Replacement Of UDFs That Implement Operations On
UDTs
The following restrictions apply to replacing UDFs that implement operations on UDTs:
•
A UDF used as a cast, ordering, or transform routine must be created in the SYSUDTLIB
database.
•
A UDF used to implement either ordering or transform functionality for a UDT can only
be replaced if all the following conditions are satisfied:
•
The REPLACE FUNCTION specification must match exactly with the existing method
specification in the dictionary.
This means that the function name, parameter list, method entry point name within
the EXTERNAL clause, and so on must all match.
•
The execution mode for the UDF being replaced must be EXECUTE PROTECTED.
If the function is currently set to EXECUTE NOT PROTECTED mode, then you must
perform an ALTER FUNCTION statement to change the mode to EXECUTE
PROTECTED before you can perform the REPLACE FUNCTION statement.
Unless all of these conditions have been met when you submit the REPLACE FUNCTION
statement, the system returns an error to the requestor.
SQL Reference: Data Definition Statements
239
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
•
A UDF that implements casting functionality for a UDT can only be replaced by
performing the following SQL statements in the order indicated:
a
DROP CAST (see “DROP CAST” on page 1003)
b
REPLACE FUNCTION
c
CREATE CAST (see “CREATE CAST/ REPLACE CAST” on page 184)
You cannot use REPLACE FUNCTION by itself to perform this task. An attempt to replace
a casting function directly using REPLACE FUNCTION aborts and returns an error to the
requestor.
Protected and Unprotected Execution Modes
By default, all UDFs are created to run in protected mode. Protected and secure modes11 are
states in which each instance of a UDF runs in a separate process. This is done to protect the
system from many common programming errors such as non-valid pointers, corrupted
stacks, and illegal computations such as divide-by-zero errors that would otherwise crash the
Teradata Database, produce problems with memory leakage, or cause other potentially
damaging results.
These problems all cause the Teradata Database to crash if they occur in unprotected mode.
UDFs can also cause the database to crash in protected mode if they corrupt the shared data
areas between the database and the protected mode UDF.
Protected mode is designed to be used for the following purposes only:
•
Testing all UDFs that are in development.
•
Running any UDFs that cause the OS to consume system resources.12
Do not use protected mode for production-ready functions that do not make OS system calls.
This is because protected mode places additional processing burdens on the system that often
result in performance degradation, while UDFs in unprotected mode run in the context of the
AMP worker task that is already being used by that query step. If you run UDFs in protected
mode, they run more slowly.
The best practice is to develop and test your UDFs on a non-production test system. You
should run any newly created UDF several hundred times, both to ensure that it does not
crash the system and to determine any performance issues that could be avoided by alternate
function design and better coding techniques. Poorly designed UDFs can be a significant
drain on system performance.
Table cardinality is an important factor in UDF performance, so any tests run against smaller
test tables on a non-production system might not scale to the same level of performance when
run against significantly larger tables in production databases.
11. The difference between a protected mode server and a secure mode server is that a protected mode server
process runs under the predefined OS user tdatuser, while a secure server process runs under the OS user
specified by the UDF in its EXTERNAL SECURITY clause. The two processes are otherwise identical.
12. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
240
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
You can use the cufconfig utility to expand the number of protected mode servers from the
default value of 2 to a maximum of 20 per AMP or PE vprocs (see Utilities and SQL Reference:
UDF, UDM, and External Stored Procedure Programming for details). The minimum is 0.
Protected mode servers consume disk resources as follows:
Number of vprocs Number of protected mode servers 256 K bytes
Total swap space required = ------------------------------------------- × ----------------------------------------------------------------------------------- × ----------------------------Node
vproc
server
In unprotected mode, a UDF is called directly by the Teradata Database rather than running as
a separate process. You should only alter a new function that does not require the OS to
allocate system context to run in unprotected mode after you have thoroughly tested and
evaluated its robustness and performance impact. Once the newly created
CPU-operations-only UDF has passed your quality measures and is ready to be put into
production use, you should alter it to run in unprotected mode.
How UDFs Handle SQL Result Codes
Because UDFs are user-written applications, it is the responsibility of the user-written code to
generate all success, warning, and exception messages.
The ANSI SQL:2003 standard defines a return code variable named SQLSTATE to accept
status code messages. All condition messages are returned to this variable in a standard ASCII
character string format.
All SQLSTATE messages are 5 characters in length. The first 2 characters define the message
class and the last 3 characters define the message subclass.
For example, consider the SQLSTATE return code ‘22021’. The class of this message, 22,
indicates a data exception condition. Its subclass, 021, indicates that a character not in the
defined repertoire was encountered.
Be aware that SQL warnings do not abort a request, while SQL exceptions do abort a request.
Note: If you perform a UDF that is not set to run in protected mode, the Teradata Database
might not trap on any errors the function generates. If this happens, the likelihood that the
error will crash your system is high. See “When to Specify Unprotected Mode” on page 22 for
more information.
You should ensure that your UDFs always return valid SQLSTATE codes. The Teradata
Database does not map SQLSTATE values returned by user-defined functions to their
equivalent SQLCODE values. All SQLSTATE codes generated by UDFs are explicitly mapped
to Teradata Database messages as indicated by the following table:
SQL Reference: Data Definition Statements
241
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
IF the UDF returns
this type of SQL
return code …
THEN the system
maps it to this
error message …
AND displays it in this format …
Warning
7505
*** Warning 7505 in dbname.udfname: SQLSTATE 01Hxx:
<user function message text>
Exception
7504
*** Error 7504 in dbname.udfname: SQLSTATE U0xxx:
<user function message text>
The string represented by <user function message text> is a user-defined error message
generated by the UDF.
The text represented by x characters in the SQLSTATE subclass is also assigned by the
user-written UDF code. All such characters must be either digits or uppercase Latin
characters.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for more
information about coding UDFs.
See SQL Reference: Fundamentals for more information about SQL exception and warning
codes.
See SQL Reference: Stored Procedures and Embedded SQL for more information about
SQLSTATE and SQLCODE.
Mandatory Function Attributes
All functions must be created with all the attributes named in the following list of mandatory
elements:
•
Name
•
Return value type
•
LANGUAGE C/CPP specification
•
NO SQL specification
•
External function name
All other attributes are optional.
Differences Between CREATE FUNCTION and REPLACE FUNCTION
A function can be created or replaced using the same syntax except for the keywords CREATE
and REPLACE.
If you specify CREATE, the function must not exist.
If you specify REPLACE, you can either create a new function or replace an existing function
with the following restriction: if the function to be replaced was originally created with a
specific function name, then that specific function name must be used for the REPLACE
FUNCTION statement.
242
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
When you replace an existing function, the replaced function does not retain the EXECUTE
NOT PROTECTED attribute if one had previously been set using the ALTER FUNCTION
statement (see “ALTER FUNCTION” on page 21).
The advantage to using REPLACE is that you can avoid having to grant the EXECUTE
privilege again to all users who already had that privilege on the function.
There are two important restrictions on replacing UDFs that perform UDT-related
functionality:
•
A UDF that is being used to implement either the ordering or transform functionality for a
UDT can only be replaced if the following conditions are all met:
•
The REPLACE FUNCTION specification must match exactly with the existing method
specification in the dictionary.
This means that the function name, parameter list, method entry point name within
the EXTERNAL clause, and so on must all match.
•
The execution mode for the UDF being replaced must be set to EXECUTE
PROTECTED.
If the UDF is currently set to run in the EXECUTE NOT PROTECTED mode, then you
must submit an ALTER FUNCTION statement (see “ALTER FUNCTION” on page 21)
to switch the mode to EXECUTE PROTECTED before you can submit the REPLACE
FUNCTION statement.
•
A UDF that is being used to implement casting functionality for a UDT can only be
replaced using the following procedure:
a
DROP CAST
b
REPLACE FUNCTION
c
CREATE CAST
An attempt to directly replace a casting function using REPLACE FUNCTION results in
an aborted request and returns an error to the requestor.
User-Defined Functions and Large Objects
The usage characteristics for a user-defined function with large object parameters or a large
object return value are the same as the usage characteristics for any other UDF. In general, you
can specify a UDF that accepts a LOB value as an argument in any context in which a UDF is
otherwise allowed. You can also use a UDF that returns a LOB value in any context in which a
value of that type is appropriate and a UDF is otherwise allowed.
As with other functions and operators, automatic type conversions can be applied to the
arguments or the return values of a UDF. You should be careful about the possible
performance implications of automatic type conversions with large objects used as UDF
parameters. For example, a function whose formal parameter is a BLOB type could be passed
a VARBYTE column as the actual parameter. The system converts the VARBYTE value into a
temporary BLOB and then passes that to the UDF. Because even a temporary BLOB is stored
on disk, the performance cost of the conversion is significant. To avoid this, you should
consider creating an overloaded function that explicitly accepts a VARBYTE argument.
SQL Reference: Data Definition Statements
243
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Another possible cause of undesired conversions is truncation. Declared length is part of the
data type. Consider a UDF whose formal parameter is declared to be BLOB(100000) AS
LOCATOR, and suppose the actual parameter is a column whose type is declared as BLOB
without a locator specification. In this case, the maximum length of the source type defaults to
2,097,088,000 bytes. Whenever the source type is longer than the target type, truncation
might occur. Because of this, an automatic conversion operation, which results in a data copy
as well as the creation of a temporary BLOB, must be generated. Therefore, whenever possible,
you should define UDFs to accept the maximum length object by omitting the length
specification.
This rule contradicts the policy for all other data types, which is that data type length
declarations should only be as long as is necessary. See SQL Reference: UDF, UDM, and
External Stored Procedure Programming for details.
Function Identifiers
Function names (see “Function Name” on page 245) are distinct from specific function names
(see “Function Class Clause” on page 251), external function names (see “External Name
Clause” on page 257), and function entry point names (see “UDF Default Location Paths” on
page 269).
The following table briefly outlines the differences among the different function identifiers:
Function
Identifier
Function name
Syntax Variable Name
function_name
Definition
The identifier used to call the function from an
SQL statement.
If no specific name is assigned to the function, then
the name stored in the data dictionary is
function_name.
If a specific name is assigned to the function, then
function_name is not the name by which the
dictionary knows the function as a database object,
and it need not be unique within its database.
Specific
function name
specific_function_name
The identifier used to define the function as a
database object in the dictionary table DBC.TVM.
External
function name
external_function_name
The external function name can be expressed in
two ways:
• As an identifier that names the entry point for
the function object. Case is significant, and the
name must match the name of the C or C++
function body.
• As a string that identifies a client-defined path
to the C or C++ function source code.
244
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Function
Identifier
Function entry
point name
Syntax Variable Name
Definition
function_entry_point_name
The identifier used to define the entry point name
of the function.
A function entry point name must be specified if
its name is different than the function name or
specific function names defined for the function.
You cannot specify function_entry_
point_name more than one time in the EXTERNAL
clause of the CREATE FUNCTION or REPLACE
FUNCTION statements.
Function Name
The function name is the identifier used to call the function from an SQL statement. It is not
necessarily the database object name that is stored in the dictionary table DBC.TVM.
IF …
THEN the name stored in DBC.TVM is its …
no specific name is
assigned to the function
function name.
a specific name is assigned
to the function
specific function name.
In this case, the function name must be unique within its database.
In this case, the function name need not be unique within its database.
See “Function Class Clause” on page 251.
The maximum length of a function name is 30 characters (see SQL Reference: Fundamentals
for a description of valid Teradata Database identifiers and a list of the characters they can
contain). Function naming follows the standard Teradata Database conventions for naming
identifiers. If you use either function_name or specific_function_name to identify the C or C++
function name, take care to follow the identifier naming conventions of the C or C++
languages.
Though you can give a function the same name as a column, you must be very careful to avoid
specifying them ambiguously. For example, if the column name is followed with a Teradata
Database-style type clause as in the following example, then the system assumes that text_find
is a reference to the function named text_find, not a reference to the identically named column
text_find:
text_find(FLOAT),
SQL Reference: Data Definition Statements
245
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
There are two ways to make your request unambiguous:
•
Use the ANSI syntax for CAST to make an explicit declaration of data type rather than a
function parameter. For example:
CAST (text_find as FLOAT)
•
Qualify the column name fully. For example:
sales.text_find (FLOAT),
In this example, sales is the table that contains the column named text_find.
You can precede the function name with its containing database name if the function is
created in a different database than your default. The scope of the name is the database in
which it is defined.
A function name need not be unique: several functions can have the same function name.
This is referred to as function name overloading (see “Function Name Overloading” on
page 247). The parameter type specifications among various overloaded function names must
be sufficiently different to be distinguishable. See “Function Name Overloading” on page 247
for a list of the rules the system uses to determine the uniqueness of a function by its
parameters. See the table in “External Body Reference Clause” on page 255 for more
information about function name usage.
To create or replace a function, the function_name must match the spelling and case of the C
or C++ function name if the specific_function_name or external_function_name clauses are
not specified. Case of the identifier is not important for calling the function. For example, a
function created with the function name Find_Text can be called using FIND_TEXT,
find_text, or fiNd_teXt and they would all invoke the Find_Text C or C++ function object
code.
You cannot create a function that has the same name as one of the intrinsic Teradata Database
functions unless the function name is enclosed in double quotes on creation and then
referenced with the name in double quotes, for example, "TRIM"(...)). You should avoid this
practice.
Function Calling Argument
The function calling argument is any simple Teradata Database SQL expression, including,
but not limited to, constant values, column references, host variables, or an expression
containing any of these, including expressions containing UDFs.
When you call a function, and that function is not stored in either your default database or in
database SYSLIB, you must fully qualify the function call with a database name. If your default
database and SYSLIB both contain functions matching the name of the called function, then
the system references the UDF in your default database. This is the only exception that
requires an explicit qualification for SYSLIB.
The argument types passed in the call must be compatible with the parameter declarations in
the function definition of an existing function. If there are several functions that have the
same name (see “Function Name Overloading” on page 247), and no qualifying database is
specified, then the particular function that is picked is determined by the following process:
246
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
1
The system searches the list of built-in functions.
If the called function has the same name as a Teradata Database built-in function, the
search stops and that function is used.
If a candidate function is not found, proceed to stage 2.
2
The system searches the list of function names in the default user database.
Candidate functions are those having the same name and number of parameters as
specified by the function call as well as the best fit based on their parameter type.
If a candidate function is not found, proceed to stage 3.
3
The system searches the list of function names in the SYSLIB database.
Candidate functions are those having the same name and number of parameters as
specified by the function call as well as the best fit based on their parameter type.
If no candidate function is found, an error is returned.
4
End of process.
The rules for selecting a best fit candidate user-defined function once its containing database
has been determined are described in “Function Name Overloading” on page 247.
Function Name Overloading
Function names need not be unique within a function class; however, functions from two
different function classes cannot have the same name within the same database. The system
uses the parameter types of identically named functions to distinguish among them, so it is
imperative that the parameter types associated with overloaded function names be sufficiently
different to be distinct.
The system uses the precedence order for compatible type parameters to determine which
function is to be invoked when several functions having the same name must be differentiated
by their parameter types. See SQL Reference: UDF, UDM, and External Stored Procedure
Programming for further information about function overloading.
The Teradata Database follows a set of parameter rules to determine the uniqueness of a
function name. These rules are provided in the following list:
•
The following numeric parameter types listed in order of precedence for determining
function uniqueness. For example, a BYTEINT fits into a SMALLINT and a SMALLINT
fits into an INTEGER. Conversely, a FLOAT does not fit into an INTEGER without a
possible loss of information.
The types are distinct and compatible. Types sharing a number are synonyms and are not
distinct from one another.
a
BYTEINT
b
SMALLINT
c
INTEGER
d
DECIMAL13
NUMERIC
SQL Reference: Data Definition Statements
247
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
e
•
FLOAT
DOUBLEPRECISION
REAL
The following character parameter types are listed in order of precedence for determining
function uniqueness.
The types are distinct and compatible. Types sharing a character are synonyms and are not
distinct from one another.14
•
•
a
CHARACTER
b
VARCHAR
CHARACTERVARYING
LONGVARCHAR
c
CHARACTER LARGE OBJECT
The following graphic parameter types are distinct and compatible. Types sharing a bullet
are synonyms and are not distinct from one another.
•
GRAPHIC
•
VARGRAPHIC
LONG VARGRAPHIC
The following byte parameter types are distinct and compatible:
•
BYTE
•
VARBYTE
•
BINARY LARGE OBJECT
•
All date, time, timestamp, and interval parameter types are distinct.
•
If the number of parameters in identically named existing functions is different or if the
function parameter types are distinct from one another in at least one parameter, then the
function being defined is considered to be unique.
•
If more than one function has the same function_name, then you must supply a
specific_function_name.
•
You can only overload function names within the same class within a given database. For
example, you cannot have a scalar function and an aggregate function with the same
function_name within the same database.
13. The size specification for DECIMAL and NUMERIC types does not affect the distinctiveness of a function.
For example, DECIMAL(8,3) and DECIMAL(6,2) are identical with respect to determining function
uniqueness.
14. The length specification of a character string does not affect the distinctiveness of a function. For example,
CHARACTER(10) and CHARACTER(5) are identical with respect to determining function uniqueness.
CHARACTER SET clauses also have no effect on the determination of function uniqueness.
248
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Parameter Names and Data Types
The parameter list contains a list of variables to be passed to the function. The list is bounded
by open and closed parentheses even if there are no parameters to be passed. In this case, the
opening and closing parentheses must be specified with a null argument.
You can specify no more than 128 parameters in a UDF parameter list.
Function parameters optionally can be named. If you specify one parameter name, then you
must name all parameters explicitly. Parameter names are standard SQL identifiers. If you do
not specify parameter names, then the system creates arbitrary names for them in the format
Pn, where n is an integer that specifies the order in which the parameters are created,
beginning with P1.
Parameter names are used by the COMMENT statement (see “COMMENT (Comment
Placing Form)” on page 166) and are reported by the HELP FUNCTION STATEMENT
statement (see “HELP FUNCTION” on page 1464). Parameter names, with their associated
database and function names, are also returned in the text of error messages when truncation
or overflow errors occur with a function call.
Each parameter type is associated with a mandatory data type to define the type of the
parameter passed to or returned by the function. The specified data type can be any valid data
type, including UDTs (see SQL Reference: Data Types and Literals for a complete list of
Teradata Database SQL data types). Character data types can also specify an associated
CHARACTER SET clause.
For character string types like VARCHAR that might have a different length depending on the
caller, the length of the parameter in the definition indicates the longest string that can be
passed. If there is an attempt to pass a longer string, the result depends on the session mode.
The following table summarizes the standard Teradata Database session mode semantics with
respect to character string truncation:
IF the session mode is …
THEN …
ANSI
any pad characters in the string are truncated silently and no truncation
notification is returned to the requestor.
A truncation exception is returned whenever non-pad characters are
truncated.
If there is a truncation exception, then the system does not call the
function. The relevant indicator values are not set to the number of
characters truncated.
Teradata
the string is truncated silently and no truncation notification message is
returned to the requestor.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for details on
parameter passing conventions for the TD_GENERAL and SQL parameter styles.
SQL Reference: Data Definition Statements
249
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Returns Clause
This mandatory clause specifies the data type of the parameter value returned by the function.
You can specify any valid data type, including UDTs. It is the responsibility of the user-written
function code to return this value in the proper form.
The defined return data type is stored as an entry in DBC.TVFields using the name
RETURN0[n], where n is a sequentially defined integer used to guarantee the uniqueness of
the value. This ensures that user-defined parameter names are not duplicated.
If the data type of the returned parameter value would be difficult for the function to create,
you can specify the optional CAST FROM option for this clause. This option explicitly casts
the returned value into the specified data type. The type casting helps with more complex
conversions to ensure they need not be embedded within the function.
The following code fragment illustrates the use of the CAST FROM clause:
...RETURNS DECIMAL(9,5) CAST FROM FLOAT...
Language Clause
This mandatory clause specifies the language in which the function source is written.
The only acceptable specifications are C and CPP.
IF the source code is written in this programming
language …
THEN the valid specification for the LANGUAGE
clause is …
C
C
C++
CPP
You can specify the Language and SQL Data Access clauses in any order.
If you only have the object code for your function body, you must ensure that it is completely
compatible with C or C++ object code, even if it was written using a different programming
language.
Note that while external stored procedures support external routine code written in Java,
UDFs do not.
Restrictions on Declaring an External C++ Function
If you specify CPP in the Language Clause, then you must declare the main C++ function as
extern “C” to ensure that the function name is not converted to an overloaded C++ name,
for example:
extern “C”
void my_cpp(long int *input_int, long int *result, char sqlstate[6])
{
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for details.
250
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
SQL Data Access Clause
This mandatory clause specifies whether SQL statements are permitted within the
user-written external routine for the function.
The only valid specification is NO SQL.
You can specify the SQL Data Access and Language clauses in any order.
Optional Function Characteristics
The following set of clauses is optional. You can specify all or none of them, and in any order,
but each clause defaults to a particular value if it is not specified.
•
Specific function name (see “Specific Function Name Clause” on page 251)
•
Function class (see “Function Class Clause” on page 251)
•
Parameter style (see “Parameter Style Clause” on page 253)
•
Deterministic characteristics (see “Deterministic Characteristics Clause” on page 254)
•
Null call (see “Null Call Clause” on page 254)
If you specify any of these clauses, you must specify them sequentially prior to specifying the
External Clause (see “External Name Clause” on page 257), which can be followed by a
Parameter Style Clause see “Parameter Style Clause” on page 253).
Specific Function Name Clause
This clause is mandatory if you are using function name overloading, but otherwise is
optional.
The clause specifies the specific name of the function. The specific function name is the name
placed in the DBC.TVM table and has the same name space as tables, views, macros, triggers,
join indexes, hash indexes, and stored procedures. A specific function name must be unique
within its containing database. See the table in “External Body Reference Clause” on page 255
for more information about function name usage.
Function Class Clause
This optional clause specifies the class of function being defined. Specify it only for aggregate
functions.
The aggregate function is invoked for each group in a SELECT statement that requires
aggregation and computes a single value for each group it is called for. You can specify an
aggregate UDF anywhere you can specify a built-in aggregate function.
A function of one class cannot have the same name as a function of another class within the
same database, even if their parameters differ. Overloading function names is only supported
within the same class of a function.
This clause is a Teradata extension to the ANSI SQL:2003 standard.
SQL Reference: Data Definition Statements
251
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Optimizing the Aggregate Cache
Appropriate management of the aggregate cache used by aggregate UDFs is very important for
optimizing their performance. Excessive cache paging can have an enormous negative effect
on the performance of an aggregate UDF.
You can specify the size of the interim aggregate cache for a UDF, which is the maximum
number of cache bytes used by that function, to a value between a minimum of 1 byte and a
maximum of 64,000 bytes. By default, the size of the aggregate cache is 64 bytes.
Allocating the optimal size for the aggregate cache is important because by doing so, you
allocate the group cache used by the function. For example, if you specify an aggregate cache
size of 64K bytes, then the maximum number of interim group cache entries is 15, which is
determined as follows:
1 Mbyte- = 15.625 ≅ 15
Number of cache entries = ----------------------64 Kbytes
If an aggregation requires more than 15 group cache entries, then those entries must be
flushed to disk more frequently than would be necessary with a smaller aggregate cache
allocation.
Aggregate UDFs use the same aggregate processing functionality as system-defined aggregate
functions like SUM and MAX (see SQL Reference: Functions and Operators). Aggregate
processing creates interim group entries to maintain the aggregation information between
rows associated with the same aggregation group. The system caches these interim group
entries to enhance performance, but in those cases where the number of interim groups
exceeds the capacity of the aggregate cache to contain them, the least recently used entries are
paged to a spool file on disk. The system does not attempt to retrieve or combine interim
group entries from spool until the last step of aggregate processing.
To achieve optimum performance, your goal is to keep all of the interim group entries in
cache by minimizing the number of aggregation phases per group. The best way to improve
aggregate cache usage for an aggregate UDF is to adjust the size of the aggregate interim group
(the aggregate storage size) to exactly what is needed: no more and no less. Aggregation works
correctly no matter what aggregate storage size you specify, but you can optimize its
performance by adjusting the interim storage size using the CLASS AGGREGATE interim_size
option when you create or replace an aggregate UDF.
The task is to optimize the trade off between maximizing the number of cache entries that can
share the aggregate cache while at the same time allocating enough memory to handle the
aggregation tasks required.
As long as the aggregate cache does not overflow, there are at most (number_of_AMPs - 1)
aggregation phases for each group, but if the aggregate cache overflows, a large number of
aggregation phases can occur, which has a negative impact on performance.
There are three variables to be considered in adjusting the aggregate storage size:
252
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Variable
Description
Aggregate cache size
This value is fixed in Teradata Database at 1 MByte.
Aggregate storage size
This value is specified by the CLASS AGGREGATE interim_size option.
The aggregate storage size can range from a minimum of 1 byte to a
maximum of 64 Kbytes, with a default value of 64 bytes.
Number of interim
group cache entries
This value depends on the aggregate storage size, and is calculated as
follows:
Aggregate cache sizeNumber of interim group cache entries = ----------------------------------------------------Aggregate storage size
Note that the number of interim aggregation groups for an aggregate UDF is a direct function
of the size of the aggregate storage specified by the UDF definition. The following table shows
two extreme examples of this ranging over three orders of magnitude.
Aggregate Storage Size
64 bytes
64 Kbytes
Number of Interim Groups That Can Be Contained in Cache
15,625
15
As noted previously, when the number of interim groups exceeds the number that can be
contained in the aggregate cache defined for the function, the cache overflows and some
number of the least recently used entries are flushed to a spool file. This paging of aggregation
groups permits an unlimited number of groups to be processed, but at the cost of an
additional aggregation phase for each aggregate cache entry written to spool plus the
performance impact of writing to, and reading from, the spool file on disk.
Parameter Style Clause
This optional clause specifies the parameter passing style to be used by the function. The
Teradata Database supports two parameter passing styles for user-defined functions:
•
SQL
•
TD_GENERAL
The default is SQL.
The SQL parameter passing style allows the code body to indicate NULL data. This cannot be
done with the TD_GENERAL parameter passing style. If you do not specify a parameter style
clause, then the system defaults to PARAMETER STYLE SQL. You can specify the parameter
style clause in one of two places:
•
SQL data access clause
•
External function name
SQL Reference: Data Definition Statements
253
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
You cannot specify the parameter style both places in the same user-defined function
definition statement. Only one parameter style clause is permitted per UDF definition.
Specific details of both options are described in SQL Reference: UDF, UDM, and External
Stored Procedure Programming.
Deterministic Characteristics Clause
This optional clause declares whether the function returns the same results for identical inputs
or not.
The Teradata Database supports two deterministic characteristics options:
•
DETERMINISTIC
A function defined to be DETERMINISTIC always returns the same results when it is
passed the identical data. For example, a function that determines the cube root of 27
always returns the value 3.
•
NOT DETERMINISTIC
A function defined to be NOT DETERMINISTIC might or might not return the same
results when it is passed the identical data. For example, a function based on the
RANDOM function (see SQL Reference: Functions and Operators) is very likely to return
different results when it is passed the same data.
The default is NOT DETERMINISTIC.
Null Call Clause
This optional clause specifies how the function handles null results. The clause has two
options:
•
CALLED ON NULL INPUT
•
RETURNS NULL ON NULL INPUT
The default is CALLED ON NULL INPUT.
The behavior of this clause is correlated with the specification you make for the parameter
style:
IF you specify this
parameter style …
THEN nulls …
SQL
can be specified for both the input values and the result value.
This is accomplished by providing an indicator value for each parameter as
well as for the result parameter.
TD_GENERAL
254
raise an exception condition.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
If any of the passed arguments is null, then the action taken depends on the option you specify
for handling nulls:
IF you specify …
THEN the function is …
CALLED ON NULL INPUT
called and evaluated.
RETURNS NULL ON NULL
INPUT
not called. Instead, it always returns a null.
and any of the parameter
values passed to the function
are null
This option is useful to avoid generating an exception condition for
functions defined with the TD_GENERAL parameter style, which
does not handle nulls.
You cannot specify RETURNS NULL ON NULL INPUT for
aggregate functions because they must always be called even if they
are passed a null.
External Body Reference Clause
The mandatory external body reference clause both declares that the function is external to
the Teradata Database and identifies the location of all the file components it needs to be able
to run.
An external function name is optional. When it is specified, it must be the name of the C or
C++ source code file on the client system to be retrieved and compiled as part of the CREATE/
REPLACE FUNCTION process.
If the external function name alone is not sufficient to specify the location of all the function
components, then you must specify a string literal that explicitly specifies the path to each of
those elements (see “External String Literal” on page 258).
In all cases, function_name is the identifier you specify when you invoke the function from
SQL statements.
You can optionally specify either or both of the following options for this clause:
•
External function name
•
Parameter style
You can specify an external function name in several different ways. See the following for
details:
•
“External String Literal” on page 258
•
“Include Name Clause” on page 261, “Library Name Clause” on page 262, “Object File
Name Clause” on page 262, “Package Name Clause” on page 263, and “Source File Name
Clause” on page 265
SQL Reference: Data Definition Statements
255
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
The following table, which is adapted from SQL Reference: UDF, UDM, and External Stored
Procedure Programming, encapsulates the various specification possibilities of this clause:
IF CREATE FUNCTION
specifies this clause …
THEN …
EXTERNAL
IF the SPECIFIC
clause is …
THEN the C or C++ function name must match
the …
specified
specific_function_name.
not specified
function_name.
If the client is channel-attached, then the C or C++ function name
must be the DDNAME for the source.
EXTERNAL NAME
external_function_name
EXTERNAL NAME 'string'
the C or C++ function name must match function_name.
If the client is channel-attached, then function_name must be the
DDNAME for the source.
'string' can specify the C or C++ function name by stipulating the F
option with a function_entry_name, which must match the name of
the C or C++ function.
The maximum length of ‘string’ is 1 000 characters.
You cannot specify the F option in ‘string’ without also specifying an
include, library, object, package, or source file name. The Teradata
Database needs one or more of these file names to link to.
If 'string' does not stipulate a function_entry_name, then the following
rules apply to the C or C++ function name:
IF the SPECIFIC
clause is …
THEN the C or C++ function name must match
the …
specified
specific_function_name.
not specified
function_name.
Note that none of these specifications can be used for Java external stored procedures.
You can specify the parameter style for the function either in this clause or in the Optional
Function Characteristics clause, but you can only specify the parameter style for a function
one time in its definition. See “Parameter Style Clause” on page 253 for more information.
256
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
External Name Clause
The purpose of the External Name clause is to specify the locations of all components needed
to create the UDF.
All files included by, or linked to, a UDF must be accessible to the database. These files can
reside on a client system or within the Teradata Database. For security reasons, the best
practice is to keep the source on the client system to ensure that the programmer writing the
function can control who can access the code. To do this, specify the C option in the external
string literal clause (see “External String Literal” on page 258) to notify the system that the
source is stored on the client. If security is not an issue, you can store the source code files on
the server. There are specific default server directories for that purpose (see “UDF Default
Location Paths” on page 269).
The system automatically copies any client-resident source, header, or object files specified in
the External Name clause to the server. Note that the system does not transport external
libraries and shared object files, which must be manually installed in the Teradata Database.
You can specify the external function name in one of three ways:
•
As an external function name identifier with optional Parameter Style clause (see
“Parameter Style Clause” on page 253).
•
As a function object name (see “Function Entry Name Clause” on page 260).
•
As a coded string that specifies the explicit path to the specified code entity (see “External
String Literal” on page 258).
IF the external
function name is …
THEN …
an identifier
it is the name of the entry point for the function object.
The identifier is case sensitive and must match the C or C++ external
function name.
a string
it is composed of either of the following:
• a C or C++ function entry point name specification
• an encoded path to the specified code entity
The maximum length of the external name string is 1,000 characters.
You can specify more than one encoded string per UDF definition, though some can only be
specified once within a list of strings. See “Include Name Clause” on page 261, “Library Name
Clause” on page 262, “Object File Name Clause” on page 262, “Package Name Clause” on
page 263, and “Source File Name Clause” on page 265 for details.
SQL Reference: Data Definition Statements
257
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
External String Literal
The external string literal specifies an encoded list of the components required to create a
UDF. When decoded, the string specifies what each component is and where it is located.
Depending on the requirements of the specific UDF, you can specify the following
components:
•
Entry point name of the function to be run (see “Function Entry Name Clause” on
page 260)
•
Include file (C or C++ header file) paths (see “Include Name Clause” on page 261)
•
System library paths (see “Library Name Clause” on page 262)
•
Object code paths (see “Object File Name Clause” on page 262)
•
Package (user-created library) paths (see “Package Name Clause” on page 263)
•
Source code paths (see “Source File Name Clause” on page 265)
For UNIX systems only, you can also specify an optional code that instructs the compiler to
generate information that can be used to analyze core files (see “Debug Option” on page 265).
The system uses the code path to access the file it specifies, then adds an appropriate extension
as it transfers that file to the UDF compile directory on the server.
It is good programming practice not to use any of the following characters as the delimiter
because they might be interpreted as a component of a path string rather than as a delimiter:
•
/(SOLIDUS)
•
\(REVERSE SOLIDUS)
•
: (COLON)
The only restriction enforced on the arbitrary delimiter character is that you must use the
same delimiter character throughout the specified path string.
The Teradata Database retrieves the source component from the specified client or server
when it requests the source or object code. The system saves the function entry point name
component in the dictionary and then uses that name to invoke the function.
You should name any include files (C/C++ header files) with the same name as specified in the
C/C++ include directive of the C or C++ source file (see SQL Reference: UDF, UDM, and
External Stored Procedure Programming).
For example for a z/OS client:
'CI¡sqltypes_td¡UDFDEFS¡CS¡myudf¡UDFSRC¡F¡theudf'
where UDFDEFS and UDFSRC are the DDNAMEs for the files on the z/OS client system.15
This clause causes the system to do the following things:
•
Retrieve the file UDFDEFS and rename it to udfdefs.h in the UDF compile directory for
the server.
•
Retrieve UDFSRC and rename it to myudf.c in the UDF compile directory for the server.
15. Whenever you refer to an IBM client file in a code path, you must identify it by its client DDNAME.
258
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
The C or C++ source myudf.c should contain the following code:
#include <udfdefs.h>
or
#include "udfdefs.h"
The clause also specifies the F option, which stipulates that the function entry name is
theudf. The C or C++ file named theudf must then have the following skeletal code:
void the udf ( ... )
{
...
}
You cannot specify the F option unless you also specify a source, object, package, or library file
in the specification string.
Suppose you specify the following skeletal CREATE FUNCTION statement, where the
omitted details are denoted by an ELLIPSIS (...) character:
CREATE FUNCTION abc(...)
...
EXTERNAL NAME ‘CS!matrix!matrix.c’;
The name of the C or C++ source file in this example is matrix.c and the C or C++
function name, based on the function name abc, must have the following skeletal code:
void abc(...)
{
...
}
Suppose you specify the following skeletal CREATE FUNCTION statement, where, again, the
omitted details are denoted by an ellipsis (...):
CREATE FUNCTION abc(...)
...
EXTERNAL NAME ‘CO!matrix!matrix.o’;
There is no source file for this function; instead, the code is an object file named matrix.o.
For this CREATE FUNCTION statement to compile successfully, there must be a function in
the specified object file named abc.
See the table at the end of the “External String Literal Examples” topic for more information
about function name usage.
You can specify the various options as many times as needed except for the package option,
which cannot be used in combination with any of the other options except the C/C++
function entry point name option.
SQL Reference: Data Definition Statements
259
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Function Entry Name Clause
The Function Entry Name clause specifies an identifier for the function_entry_name variable
as it is defined in its C or C++ module. It must match the function entry point name when the
source is compiled and linked into a shared library. The function entry point name is used
when the function defined by this statement is called.
You must specify this clause if the external function entry point name is different than
function_name or specific_function_name. The string specifies the entry point name of the
function, which is its external name.
You can only specify one function entry name per UDF definition.
The syntax for this clause is as follows:
F¡function_entry_name
The character ¡ represents a user-defined delimiter.
Follow this procedure to specify a function entry name string:
1
Begin the clause with the character F, which indicates that the characters that follow are the
function entry name for the UDF.
2
Specify an arbitrary delimiter character to separate the F code and the function entry
name specified in the string.
3
Specify the function entry name for the UDF.
This is the name of the C or C++ function object code.
4
End of procedure.
Client-Server UDF Code Specification
You must specify whether the UDF code for include files, object files, and source files is
located on the client system or on the server system. To do this, you specify C for client or S for
server.
UDF code for library and package files is always located on the server, but you still must
specify the S location code for any library or package file paths you specify.
The character used to separate entities in the path specification is platform-specific when the
file is stored on a client system, but not when the file is on the server.
260
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
The following table provides more information about writing the client and server location
specifications for include, object, or source files:
IF you specify this
location code …
C
THEN you …
must format the specification in the form required by the client application, for
example, BTEQ.
Refer to the appropriate client documentation for information about the
required form of presentation.
S
can use either the SOLIDUS character (/) or the REVERSE SOLIDUS character
(\) as the separator in the path specification for all server operating systems.
Include Name Clause
The Include Name clause specifies an explicit path to an include file that is to be used for this
UDF definition.
The syntax for this clause is as follows:
CI¡name_on_server¡include_name
or
SI¡name_on_server¡include_name
The character ¡ represents a user-defined delimiter.
Perform the following procedure for specifying an include file name string:
1
Begin the clause with the appropriate client or server location code.
IF you specify this code …
THEN the source or object code for the function is stored on the …
C
client.
S
server.
2
Type the character I to indicate this is an include file specification.
3
Specify an arbitrary delimiter character to separate the I code and the name_on_server
variable specified in the string.
4
Specify the name assigned to the include file, without the .h extension, on the server. The
server adds the .h extension.
All names on server must be unique among the UDFs and external stored procedures
created within the same database. If the CREATE/REPLACE FUNCTION definition
includes a nonunique name_on_server specification, the system does not create it.
The C or C++ source must have an include statement in the following form:
#include <name_on_server.h>
5
Specify your delimiter character to separate the name_on_server from the include_name.
SQL Reference: Data Definition Statements
261
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
6
Specify the path and name of the include file.
IF the include file is
on the …
client
THEN you …
must format the specification in the form required by the client
application, for example, BTEQ.
Refer to the appropriate client documentation for information about the
required form of presentation.
server
7
can use either the SOLIDUS character (/) or the REVERSE SOLIDUS
character (\) as the separator in the path specification for all server
operating systems.
End of procedure.
Library Name Clause
The Library Name clause specifies the name of a non-standard library file on the server that
would not normally be linked with the UDF being defined.
The syntax for this clause is as follows:
SL¡library_name
The character ¡ represents a user-defined delimiter.
Perform the following procedure for specifying a library file name string:
1
Begin the clause with the character S to indicate this is a server specification.
2
Type the character L to indicate this is a library file specification.
3
Specify an arbitrary delimiter character to separate the L code and the library name
specified in the string.
4
Specify the name assigned to the non-standard library file on the server. The server
automatically adds prefix or suffix values as needed.
The path must name a server library that is already installed on the system.
You can use either \ or / characters to specify the path for all operating systems.
5
End of procedure.
Object File Name Clause
The Object File Name clause specifies an explicit path to an object file that is to be used for
this UDF definition.
The syntax for this clause is either of the following:
•
CO¡name_on_server¡object_name
•
SO¡name_on_server¡object_name
The character ¡ represents a user-defined delimiter.
262
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Perform the following procedure for specifying an object file name string:
1
Begin the clause with the appropriate client or server location code.
IF you specify
this code …
THEN the source or object code for the function is stored on the …
C
client.
S
server.
2
Type the character O to indicate this is an object file specification.
3
Specify an arbitrary delimiter character to separate the O code and the name_on_server
variable specified in the string.
4
Specify the name assigned to the object file on the server. Do not specify an extension for
this file name.
All names on server must be unique among the UDFs and external stored procedures
created within the same database. If the CREATE/REPLACE FUNCTION definition
includes a nonunique name_on_server specification, the system does not create it.
5
Specify your delimiter character to separate the name_on_server from the object_name.
6
Specify the path and name of the object file.
IF the object file is on the …
THEN you …
client
must format the specification in the form required by the client
application, for example, BTEQ.
Refer to the appropriate client documentation for information
about the required form of presentation.
server
7
can use either the SOLIDUS character (/) or the REVERSE
SOLIDUS character (\) as the separator in the path specification
for all server operating systems.
End of procedure.
Package Name Clause
The Package Name clause specifies an explicit path to a package file that is to be used for this
UDF definition. Packages are libraries that can contain UDFs and other functions to be called
by a UDF.
A typical package includes a function library as well as a script that contains all the necessary
SQL DDL and DCL statements to create the functions and make them available to users.
SQL Reference: Data Definition Statements
263
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
For this operating system …
A package is a shared object file with this extension …
UNIX
.so
Linux
Windows
• .dll
• .lib
Windows packages require both a .dll and a .lib file.
Package files must be distributed to all server nodes.
You cannot specify the package option with any other encoded path string clause, but you can
specify it with a function entry point name string (see “External Name Clause” on page 257).
To distribute a third party package to a Teradata Database node, use their documented
installation procedure. If you are installing a package developed by your programming staff,
you can use any of the following general procedures:
•
Install the package in a specific directory and then use PCL to distribute it to all nodes.
•
FTP the package from a client system.
•
Use the Teradata-supplied stored procedure named installsp, which is stored in SYSLIB.
For instructions on how to use installsp, see SQL Reference: UDF, UDM, and External
Stored Procedure Programming.
The syntax for this clause is as follows:
SP¡package_name
The character ¡ represents a user-defined delimiter.
Perform the following procedure for specifying a package file name string:
1
Begin the clause with the character S to indicate this is a server specification.
2
Type the character P to indicate this is a package file specification.
3
Specify an arbitrary delimiter character to separate the P code and the package name
specified in the string.
4
Specify the path and name assigned to the package file on the server. You must specify the
appropriate file extension for the server operating system.
FOR this operating system …
THE package file extension must be …
UNIX
.so
Windows
.lib
The path must name a package that is already installed on the system and that has been
distributed to all its nodes.
You can use either \ or / characters to specify the path for all platforms.
264
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
5
End of procedure.
The maximum package path length is 256 characters.
Source File Name Clause
The Source File Name clause specifies the location of an object file that is to be used for this
UDF definition.
The syntax for this clause is either of the following:
•
CS¡name_on_server¡source_name
•
SS¡name_on_server¡source_name
The character ¡ represents a user-defined delimiter.
Perform the following procedure for specifying a source file name string:
1
Begin the clause with the appropriate client or server location code.
IF you specify this
code …
THEN the source or object code for the function is stored on the …
C
client.
S
server.
2
Type the character S to indicate this is a source file specification.
3
Specify an arbitrary delimiter character to separate the S code and the name_on_server
variable specified in the string.
4
Specify the name assigned to the source file on the server.
All names on server must be unique among the UDFs and external stored procedures
created within the same database. If the CREATE/REPLACE FUNCTION definition
includes a nonunique name_on_server specification, the system does not create it.
5
Specify your delimiter character to separate the name_on_server from the source_name.
6
Specify the path and name of the source file.
You can use either \ or / characters to specify the path for all platforms.
7
End of procedure.
Debug Option
The Teradata Database does not provide specific debugging support for user-defined
functions; however, for UNIX systems only, you can instruct CREATE FUNCTION to compile
the C or C++ object code for a UDF with debug symbol information that can then be used by
third party debugging tools to analyze core dumps. The debug option is not supported for
servers running the Windows and Linux operating systems.
The option provides the capability of dumping the contents of local variables in the stack
frame for the UDF in the core file (see SQL Reference: UDF, UDM, and External Stored
Procedure Programming).
SQL Reference: Data Definition Statements
265
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
A side effect of specifying the D option is that linked libraries become larger because they
must also contain all the symbol information.
You can specify the D option at any point in the external string literal specification. The D
must be bounded by the same delimiter you use to code the rest of the external string literal
specification.
IF you …
THEN the system …
specify the D option
adds the -G option to code compiled on UNIX systems.
This indicates that the C or C++ compiler should compile the code
with debug symbols.
do not specify the D option
only makes the traceback of the function call available for debugging
purposes.
A side effect of specifying this option is that the .so files for the UDF are larger than those
generated without the option because they must also contain all the symbolic information.
External String Literal Examples
The following examples demonstrate various UDF external string literals:
Example 1
The following example indicates that the source is to be obtained from the client, probably a
Windows system, from absolute directory UDF Source. The file name on the server and the
source file name are both sales.c. The function entry name is sales1 and the function is
to be compiled with debug symbols.
'CS¡sales¡C:\UDF Source\sales.c¡F¡sales1¡D'
Example 2
In the following example, the object is to be obtained from the client, which is probably a
UNIX system. udfdev/imagef.o is the relative path to udfdev/imagef.o from the
home or current client directory for the logged on user. The file name on the client is img.o.
The name of the object it retrieves is imagef.o, and the function entry name for the UDF is
img_match.
'CO¡img¡/udfdev/imagef.o¡F¡img_match'
Example 3
The following example indicates that the package in absolute directory
C:\Program Files\NCR_Miner\TeraMiner.lib expects the UDF to be specified in
library TeraMiner.lib. The function name it expects is the same as the specific name
specified in the create function call.
'SP¡C:\Program Files\NCR_Miner\TeraMiner.LIB'
266
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Example 4
The following example indicates that the header file udf_types.h and the C source file
stdvar.c to be used for the UDF are to be found on the client, which is probably a UNIX
system. /headers/udf_types.h is the relative path from the home or current client
directory for the logged on user to the header file and /src/stdvar.c is the relative path to
the C source file. The function name in the C source code is called stdvar. Both files have the
same name on the server.
'CI¡udf_types¡headers/udf_types.h¡CS:stdvar¡src/stdvar.c¡F¡stdvar'
The table on the following page summarizes the naming issues for the EXTERNAL NAME
clause and its various components.
SQL Reference: Data Definition Statements
267
268
IF you specify this function
name …
THEN the source file
name is the same as …
AND the function name
in DBC.TVM is the same
as …
AND the C/C++ function
name is the same as …
function_name only
function_name
function_name
function_name
Comments
function_name must be unique within its
database.
If you add a new function that has the same
function_name within the same database,
then you must specify a different
specific_function_name to make the two
functions distinct.
function_name and
specific_function_name
specific_function_name
specific_function_name
specific_function_name
specific_function_name must be unique
within its database.
function_name and
external_function_name
external_function_name
function_name
function_entry_name
specific_function_name must be unique
within its database.
function_name and
function_entry_name
as part of ‘string’
source_name as specified
in ‘string’
function_name
function_entry_name
function_name
function_name
If you add a new function that has the same
function_name within the same database,
then you must specify a different
specific_function_name to make the two
functions distinct.
specific_function_name
external_function_name
function_name and
‘string’ but no
function_entry_name
SQL Reference: Data Definition Statements
function_name and
specific_function_name and
function_entry_name
but not as ‘string’
external_function_name
function_name and
specific_function_name and
function_entry_name
as ‘string’
source_name as specified
in ‘string’
function_entry_name if
F option is specified
specific_function_name
if F option is not
specified
specific_function_name must be unique
within its database.
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
UDF Default Location Paths
User-defined functions expect information to be in certain default locations when they are
created or performed.
The following list catalogs the default path locations used by UDFs for the following purposes:
•
Store UDF source files
•
Compile UDF source files
•
Store .dll or .so files
•
Store shared memory files
Note that the temporary folders path for the Teradata Database on Windows systems is a
system parameter defined during installation that is usually found at the following location:
C:\Program Files\Teradata\TDAT\tdconfig
This path is represented symbolically in the following table as <TdatTemp>.
Although <TdatTemp> is the standard Windows path, you might have installed your system
using a different path. Always ensure that you use the path specified when your system was
installed.
The table on the following page documents the default directory paths for these resources and
activities:
SQL Reference: Data Definition Statements
269
270
Files/Directories
Header file
Windows
C:\Program Files\
NCR\TDAT\LTDBMS\etc
Linux
/opt/teradata/
tdat/tdconfig/
tdbs_udf/usr/
UNIX
/tpasw/etc
Description
The header file sqltypes_td.h must be
specified with an include directive in the UDF
source.
You can copy this file if you code or compile the
UDF outside of the database.
Source directory
path
C:\<TdatTemp>\
Teradata\tdbs_udf\
usr\
/opt/teradata/
tdat/tdconfig/
tdbs_udf/usr/
/Teradata/
tdbs_udf/usr/
The default directory to search for source files.
If the source or object file is on the server in this
directory, then you can specify the relative path from
this directory for any server components specified in
the external name string.
This applies to all the following file types:
•
•
•
•
Include
Object
Package
Source
Compiler path
/usr/bin/gcc
The default directory to search for the C/C++
compiler.
Linker path
/usr/bin/ld
The default directory to search for the C/C++ linker.
Compiler
temporary path
C:\<TdatTemp>\
UDFTemp\
/opt/teradata/
tdat/tdtemp/
UDFTemp/
/tmp/UDFTemp/
the temporary directory where UDFs are compiled
SQL Reference: Data Definition Statements
Any files needed for the compilation process are
moved here. This includes source files from the
server or client as well as object and header files, if
needed.
Temporary compilation directories only exist during
the duration of a compilation.
UDF library
path
C:\<TdatTemp>\
udflib\
/opt/teradata/
tdat/tdconfig/
udflib/
/ntos/udflib/
the directory where dynamically linked libraries are
stored.
UDF server
memory path
C:\<TdatTemp>\
udfsrv\
/opt/teradata/
tdat/tdtemp/
udfsrv/
/tmp/udfsrv/
the directory where shared memory files used for the
execution of protected mode UDFs are stored.
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
UDF .so and .dll Linkage Information
There is only one .so or .dll file per database per node for all the UDFs, table UDFs, and
external stored procedures in that database.
Whenever you create, replace, or drop a UDF, the UDF .so or .dll file for that database has
to be relinked with all the other UDF object files and then redistributed to all the nodes.
The following example shows the output of a UDF creation on a UNIX system. The .so file,
libudf_03ee_n.so, increments each time a UDF is created, replaced, or dropped. This
CREATE FUNCTION operation was the eighth such UDF-related operation in the current
database, so the .so file is named libudf_03ee_8.so.
The 5607 Warning message is normal.
CREATE FUNCTION another(
strexp VARCHAR(512),
n1
INTEGER)
RETURNS VARCHAR(512)
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME 'SS!another!another.c!F!another';
*** Function has been created.
*** Warning: 5607 Check output for possible warnings encountered in
compiling XSP/UDF.
*** Total elapsed time was 5 seconds.
Check output for possible compilation warnings.
-----------------------------------------------------------/usr/bin/cc -Xc -I /tpasw/etc -c -o another.o another.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -Xc -I /tpasw/etc -c -o pre_another.o pre_another.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ee_8.so
another.o pre_another.o pre_really_long_function_name.o
long_name.o pre_udf_scalar_substr.o substr.o pre_Find_Text.o
pattern.o pre_char2hexint.o char2hexint.o
-ludf -lmw -lm
Similarly, the following REPLACE FUNCTION was the tenth such UDF-related operation in
the current database, so the .so file is named libudf_03ee_10.so.
Again, the 5607 Warning message is normal.
SQL Reference: Data Definition Statements
271
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
REPLACE FUNCTION another (
strexp VARCHAR(512),
n2
INTEGER)
RETURNS VARCHAR(512)
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME 'SS!another!another.c!F!another';
*** Function has been created.
*** Warning: 5607 Check output for possible warnings encountered in
compiling XSP/UDF.
*** Total elapsed time was 1 second.
Check output for possible compilation warnings.
-----------------------------------------------------------/usr/bin/cc -Xc -I /tpasw/etc -c -o another.o another.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -Xc -I /tpasw/etc -c -o pre_another.o pre_another.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ee_10.so
another.o pre_another.o pre_Find_Text.o pattern.o
pre_udf_scalar_substr.o substr.o
pre_really_long_function_name.o long_name.o pre_char2hexint.o
char2hexint.o
-ludf -lmw -lm
External Security Clause
This clause is mandatory for all functions that perform operating system I/O. Failing to
specify this clause for a function that performs I/O can produce unpredictable results and
even cause the database, if not the entire system, to reset.
Note that authorization_name is an optional Teradata extension to the ANSI SQL:2003
standard.
272
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
When a function definition specifies EXTERNAL SECURITY DEFINER, then that function
executes:
•
Under the OS user associated with the specified external authorization using the context of
that user.
IF the UDF runs in this mode …
THEN the OS user must be …
protected
tdatuser, which must be a member of the tdatudf OS group.
secure
an OS user assigned to an authorization name using the
CREATE AUTHORIZATION statement (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174).
The specified OS user must belong to one of the following OS
groups:
• tdatudf.
• the OS group name specified by the
SecureGroupMembership field of the cufconfig utility (see
Utilities).
•
The external security authorization associated with the function must be contained within
the same database as the function (see “CREATE AUTHORIZATION/ REPLACE
AUTHORIZATION” on page 174).
The following rules apply:
•
If you do not specify an authorization name, then you must create a default DEFINER
authorization name before a user attempts to execute the function (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174).
•
If you have specified an authorization name, then an authorization object with that name
must be created before you can execute the function (see “CREATE AUTHORIZATION/
REPLACE AUTHORIZATION” on page 174).
The system returns a warning message to the requestor when no authorization name exists
at the time the UDF is being created.
Example 1
This request creates a user-defined function on a UNIX system. The UDF looks for a C source
code file named find_text.c on the client system in the current directory of the logged on
user. The function name must be find_text, which is its entry point name.
The example creates a function that searches for a user-specified test pattern within a
user-specified character string. The maximum length search string and pattern string the
function allows is 500 bytes. The result is a character value of either T or F, representing true
(the test pattern is found in the searched string) or false (the test pattern is not found in the
searched string).
SQL Reference: Data Definition Statements
273
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
CREATE FUNCTION find_text (
searched_string VARCHAR(500),
pattern VARCHAR(500))
RETURNS CHARACTER
LANGUAGE C
NO SQL
EXTERNAL
PARAMETER STYLE SQL;
*** Function has been created.
*** Warning: 5607 Check output for possible warnings encountered in
compiling XSP/UDF.
*** Total elapsed time was 5 seconds.
Check output for possible compilation warnings.
-----------------------------------------------------------/usr/bin/cc -Xc -I /tpasw/etc -c -o find_text.o find_text.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -Xc -I /tpasw/etc -c -o pre_another.o pre_another.c
Teradata High Performance C Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ee_11.so
find_text.o pre_find_text.o pre_really_long_function_name.o
long_name.o pre_udf_scalar_substr.o substr.o pre_Find_Text.o
pattern.o pre_char2hexint.o char2hexint.o
-ludf -lmw -lm
The following SELECT request that searches for a specific text description in documents
having a date not less than a specified age shows how the function find_text might be used:
USING (age DATE, look_for VARCHAR(500))
SELECT doc_number, text
FROM documents
WHERE (:age <= doc_copyright
AND
(find_text(text, :look_for) = ‘T’);
Example 2: Parsing an XML Document
One example where scalar UDFs are useful is scanning an XML document and returning
specified content, after that document has been stored inside the database. The following
example is of a UDF that uses XPath, which is a set of syntax rules that allow you to navigate
an XML document. XPath, which has a function similar to substring, uses path expressions to
identify nodes in an XML document.
Depending on your requirements, the XML document could be stored as a CLOB (Character
Large Object) or as a VARCHAR column. The former is illustrated in the graphic below, while
the following prototype uses the latter.
In this example below, the XML document is stored inside Teradata Database as one
VARCHAR column, XMLOrder. The base table, OrderLog, only contains only two columns,
PONum and the VARCHAR column.
274
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Here is the XML document:
<?xml version="1.0"?>
<ROOT>
<ORDER>
<DATE>8/22/2004</DATE>
<PO_NUMBER>101</PO_NUMBER>
<BILLTO>Mike</BILLTO>
<ITEMS>
<ITEM>
<PARTNUM>101</PARTNUM>
<DESC>Partners Conference Ticket</DESC>
<USPRICE>1200.00</USPRICE>
</ITEM>
<ITEM>
<PARTNUM>147</PARTNUM>
<DESC>V2R5.1 UDF Programming</DESC>
<USPRICE>28.95</USPRICE>
</ITEM>
</ITEMS>
</ORDER>
</ROOT>
<?xml version="1.0"?>
<ROOT>
<ORDER>
<DATE>08/12/2004</DATE>
<PO_NUMBER>108</PO_NUMBER>
<BILLTO>Rick</BILLTO>
<ITEMS>
<ITEM>
<PARTNUM>101</PARTNUM>
<DESC>Partners Conference Ticket</DESC>
<USPRICE>1200.00</USPRICE>
</ITEM>
<ITEM>
<PARTNUM>148</PARTNUM>
<DESC>V2R5.1 Stored Procedures and Embedded SQL</DESC>
<USPRICE>28.95</USPRICE>
</ITEM>
</ITEMS>
</ORDER>
</ROOT>
The DDL for the orderlog table looks like this:
CREATE SET TABLE orderlog, NO FALLBACK,
NO BEFORE JOURNAL,
NO AFTER JOURNAL,
CHECKSUM = DEFAULT (
PONum
INTEGER NOT NULL,
XMLOrder VARCHAR(63,000) )
UNIQUE PRIMARY INDEX ( PONum );
The following SELECT request references the XpathValue UDF that uses XPath to extract
element and attribute content from the XML document. The arguments passed within the
SELECT statement, such as the BILLTO name, are then used by XPath to search each
document in the table. When a document having that specific billing name is identified, then
the associated PO number and date are returned as output arguments.
SQL Reference: Data Definition Statements
275
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
SELECT XPathValue(O.xmlOrder, '//ORDER/PO_NUMBER/*') AS PO_Number,
XPathValue(O.xmlOrder, '//ORDER/DATE/*') AS theDate
FROM OrderLog O
WHERE XPathValue(O.xmlOrder,'//ORDER/BILLTO/*') = 'Mike';
And the output of the query that uses XPathValue UDF looks like this:
PO_Number
TheDate
----------- ---------------101
8/22/2004
Example 3
This example creates a scalar UDF that writes a message to an external queue. The function
calls an MQ access module, identical to the access module a TPump job or other utility might
use when processing from a queue.
The SQL is a simple SELECT request that contains nothing in the select list but the scalar UDF
and the arguments it expects. When this statement is performed, it produces the message,
'Hello World,' which is placed on an MQ queue on the client:
SELECT WriteMQ('queue.manager.1','QUEUE1','CHANNEL1/TCP/
153.64.119.177', 'Hello World');
The parameters passed are the queue manager (qmgr), queue name (qnm), client
communication channel (channel), and the message itself (vcmsg), respectively.
The following is the DDL used to replace or create the function:
CREATE FUNCTION WriteMQ(
qmgr
VARCHAR(256),
qnm
VARCHAR(256),
channel VARCHAR(256),
vcmsg
VARCHAR(32000))
RETURNS INTEGER
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME 'F:emruwmq:SI:cmqc:/usr/include/cmqc.h:SL:mqic
:SL:mqmcs:SS:emruwmq:/home/rmh/projects/emruwmq/emruwmq.c';
Example 4
Now consider a somewhat broader use of the UDF defined in “Example 3” on page 276. In
this example, you retrieve dictionary information from within Teradata Database and write it
to an external MQ queue on a client system.
To do this, you invoke the WriteMQ UDF for each row found in DBC.Tables that meets the
requirements specified in the SELECT request WHERE clause. The SELECT request
concatenates the database and table names, creating a VARCHAR string that becomes the
input argument to the UDF, which then writes the concatenated databasename.tablename text
as a message to the MQ queue.
276
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
SELECT COUNT(*) AS SentMsgs
FROM
(SELECT WriteMQ
('queue.manager.1','QUEUE1','CHANNEL1/TCP/153.64.119.177',
Trim(databasename)||'.'||trim(TableName)) AS c1
FROM DBC.Tables
WHERE TableKind = 'T')T;
What this example illustrates is the ease of sending an entire result set of an arbitrary SQL
statement to a queue that is completely outside Teradata Database.
Example 5: EXTERNAL SECURITY Clause
Suppose you have defined the following external authorization object:
CREATE AUTHORIZATION DEFINER sales
USER 'salesdept'
PASSWORD 'secret';
You now create the following UDF:
CREATE FUNCTION sales_collect(store_number INTEGER, item_no INTEGER)
RETURNS INTEGER
LANGUAGE C
NO SQL
EXTERNAL 'cs!salecol!salecollector.c'
PARAMETER STYLE SQL
EXTERNAL SECURITY DEFINER sales;
This function collects data associated with sales for a given store for a given item number
(item_no) and returns the number of items sold. One possible, albeit contrived, scenario
would have the function communicating with the store via a network interface. The function
is created using the DEFINER context. This means that when a user logs onto its database
account and executes an SQL request that invokes this function, it uses the logon ID associated
with the sales authorization object, not the user that is executing the invoking SQL request. In
this example, OS user salesdept has access to the external data the function reads to obtain the
information it needs.
SQL Reference: Data Definition Statements
277
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION/ REPLACE FUNCTION
Related Topics
See the following statements for more information about user-defined functions and external
authorization:
•
“ALTER FUNCTION” on page 21
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303
•
“DROP AUTHORIZATION” on page 1001
•
“DROP FUNCTION” on page 1013
•
“RENAME FUNCTION” on page 1104
•
“SET SESSION FUNCTION TRACE” on page 1162
•
“HELP FUNCTION” on page 1464
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
Also see SQL Reference: UDF, UDM, and External Stored Procedure Programming for
guidelines about coding external user-defined functions.
278
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
CREATE FUNCTION (Table Form)
Purpose
Creates a table function definition.
Syntax
function_name
FUNCTION
CREATE
A
database_name.
REPLACE
,
A
(
)
B
parameter
data type
parameter_name
,
B
RETURNS
column_name
(
TABLE
VARYING COLUMNS
C
language_clause
SQL_data_access
data_type
(
C
)
maximum_output_columns
(
D
SQL_data_access
specific_function_name
SPECIFIC
language_clause
database_name.
PARAMETER STYLE
SQL
DETERMINISTIC
NOT
CALLED ON NULL INPUT
specific_function_name
SPECIFIC
database_name.
PARAMETER STYLE
language_clause
SQL_data_access
SQL_data_access
language_clause
SQL
DETERMINISTIC
NOT
CALLED ON NULL INPUT
D
E
EXTERNAL
NAME
external_function_name
'
F
D
S
C
delimiter
delimiter
function_entry_name
'
I delimiter name_on_server delimiter include_name
L delimiter library_name
O delimiter name_on_server delimiter object_name
P delimiter package_name
S delimiter name_on_server delimiter source_name
E
PARAMETER STYLE
SQL
EXTERNAL SECURITY
;
DEFINER
authorization_name
INVOKER
SQL Reference: Data Definition Statements
1101C228
279
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Parameter, Return, and External Function Data Types
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
(fractional_seconds_precision)
WITH TIMEZONE
TIMESTAMP
(fractional_seconds_precision)
WITH TIMEZONE
INTERVAL YEAR
(precision)
TO MONTH
INTERVAL MONTH
(precision)
INTERVAL DAY
TO
(precision)
HOUR
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL HOUR
TO
(precision)
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL MINUTE
(precision)
TO SECOND
(- fractional_seconds_precision - )
INTERVAL SECOND
(precision
)
,fractional_seconds_precision
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
BINARY LARGE OBJECT
(
integer
(
G
K
M
BLOB
AS LOCATOR
UDT_name
SYSUDTLIB.
CHAR
BYTE
( integer )
CHARACTER SET
GRAPHIC
VARCHAR
server_character_set
( integer )
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
CHARACTER LARGE OBJECT
CLOB
280
( integer (
G
K
M
AS LOCATOR
1101A407
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
where:
Syntax element …
Specifies …
database_name
an optional database name specified if the function is to be created
or replaced in a non-default database.
If you use the recommended SYSLIB database as your UDF
depository (see “Function Calling Argument” on page 246), you
must modify the size of its permanent space and grant appropriate
access rights on it because it is created with 0 permanent space and
without access privileges.
Users must have the EXECUTE FUNCTION privilege on any UDF
they run from SYSLIB.
If you do not specify a database name, then the system creates or
replaces the function within the current database.
function_name
the calling name for the function.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the function name as short as possible (see
“Maximum Size of Teradata UNIX MP-RAS Command Line
Argument Affects Names and Number of External Routines in a
Database” on page 238).
You cannot give a UDF the same name as an existing Teradata
Database-supplied function (also known as an intrinsic function)
unless you enclose the name in double quotation marks. For
example, “TRIM”(). Using the names of intrinsic functions for
UDFs is a poor programming practice and should be avoided.
function_name must match the spelling and case of the C function
name exactly if you do not specify a specific_function_name or
external_function_name. This applies only to the definition of the
function, not to its use.
SQL supports function name overloading within the same function
class (see “CLASS function_class” on page 227), so function_name
need not be unique within its class; however, you cannot give the
same name to both a scalar and an aggregate function within the
same database.
Parameter data types and number of parameters are used to
distinguish among different functions within the same class that
have the same function_name.
See SQL Reference: UDF, UDM, and External Stored Procedure
Programming for further information about function overloading.
See the following sections for further information:
•
•
•
•
•
SQL Reference: Data Definition Statements
“Function Identifiers” on page 244
“Function Name” on page 245
“Function Calling Argument” on page 246
“Function Name Overloading” on page 247
“Parameter Names and Data Types” on page 249
281
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
[parameter_name]
parameter_data_type
a parenthetical comma-separated list of data types and optional
parameter names for the variables to be passed to the function.
The maximum number of parameters a UDF accepts is 128.
BLOB and CLOB parameter data types must be represented by a
locator (see SQL Reference: Data Manipulation Statements for a
description of locators), in contrast with RETURN TABLE clause
LOB column data types, which must not be represented by locators
(see “data_type” on page 283). Also see “Example 7: Different LOB
Specifications for Parameter and RETURNS TABLE Clauses” on
page 300).
The Teradata Database does not support in-memory LOB
parameters: an AS LOCATOR phrase must be specified for each
LOB parameter.
Note, however, that whenever a LOB that requires data type
conversion is passed to a UDF, the LOB must be materialized for the
conversion to take place.
Table UDFs do not support UDTs as parameter_data_types.
You must specify opening and closing parentheses even if no
parameters are to be passed to the function.
If you specify one parameter name, then you must specify names for
all the parameters passed to the function.
If you do not specify parameter names, the system assigns unique
names to them in the form P1, P2, …, Pn. These names are used in
the COMMENT statement (see “COMMENT (Comment Placing
Form)” on page 166) and displayed in the report produced by the
HELP FUNCTION statement (see “HELP FUNCTION” on
page 1464), and appear in the text of error messages.
The data type associated with each parameter is the type of the
parameter or returned value. All Teradata Database data types are
valid. Character data can also specify a CHARACTER SET clause.
For data types that take a length or size specification, like BYTE,
CHARACTER, DECIMAL, VARCHAR, and so on, the size of the
parameter indicates the largest number of bytes that can be passed
(see “Parameter Names and Data Types” on page 249).
RETURNS TABLE
282
that the function returns a set of rows in a standard relational table.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
column_name
the name of a column in the set of rows to be returned by the
function. You must define at least one column name and its data
type for any table function definition.
Each column name is limited to a maximum of 30 characters, with
the same restrictions as other object identifiers. See SQL Reference:
Fundamentals for a description of Teradata Database identifiers and
a list of the characters they can contain.
The maximum number of columns you can specify is 2,048.
You cannot specify a column_name having a UDT type.
If one of the specified columns has a LOB data type, then you must
define at least one other non-LOB column.
The complete set of column names and their accompanying data
types defines the structure of the table the function returns to the
caller.
data_type
a data type for each column name you specify.
If the type is one of the CHARACTER family, then you can also
specify a CHARACTER SET clause.
If the data type for a returned column is either BLOB or CLOB, then
you cannot specify it with an AS LOCATOR phrase. Such a
specification aborts the request and returns an error to the
requestor.
This is in direct contrast with the specification of LOB parameter
data types, which must be specified with an AS LOCATOR phrase
(see “[parameter_name] parameter_data_type” on page 282). Also
see “Example 7: Different LOB Specifications for Parameter and
RETURNS TABLE Clauses” on page 300).
The type cannot be a UDT.
You cannot specify any other attributes for a column other than its
data type and a CHARACTER SET clause for character data types.
VARYING COLUMNS
(maximum_output_columns)
that the number of output columns to be returned by the function is
not known before it is invoked, so limit them to a maximum of
maximum_output_columns columns.
The upper limit is 2,048 columns.
There is no default value.
SQL Reference: Data Definition Statements
283
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
language_clause
a code that represents the programming language in which the table
function is written.
The valid languages for writing UDFs are C and C++.
IF the UDF is written
in this language …
THEN the code for language_clause is …
C
C
C++
CPP
This must be specified as LANGUAGE C or LANGUAGE CPP even
if the table function is supplied in object form.
If the table function object is not written in C or C++, it must be
compatible with C or C++ object code.
This clause is mandatory.
See “Language Clause” on page 250.
SQL_data_access
whether the external function body accesses the database or contains
SQL statements
This must be specified as NO SQL.
This clause is mandatory.
See “SQL Data Access Clause” on page 251.
SPECIFIC [database_name.]
specific_function_name
the specific name for the function.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the specific function name as short as
possible (see “Maximum Size of Teradata UNIX MP-RAS Command
Line Argument Affects Names and Number of External Routines in
a Database” on page 238).
Unlike function_name (see “function_name (continued)” on
page 225), specific_function_name must be unique within the
database.
This name is stored in DBC.TVM as the name of the UDF database
object (see “Function Identifiers” on page 244 and “External Body
Reference Clause” on page 255).
This clause is mandatory for overloaded function_names, but
otherwise optional and can only be specified once per function
definition.
See “Specific Function Name Clause” on page 251.
284
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
PARAMETER STYLE
the parameter passing convention to be used when passing
parameters to the function.
SQL is the only valid parameter style.
The SQL parameter style uses indicator variables to pass arguments.
As a result, you can always pass nulls as inputs and return them in
results.
The specified parameter style must match the parameter passing
convention of the external function.
If you do not specify a parameter style at this point, you can specify
one with the external body reference.
This clause is optional and can only be specified once per function
definition.
See “Parameter Style Clause” on page 253 for more information on
parameter styles.
[NOT] DETERMINISTIC
whether the function returns identical results for identical inputs.
For example, if the function calls a random number generator as
part of its processing, then the results of a function call cannot be
known in advance of making the call and the function is NOT
DETERMINISTIC.
The default is NOT DETERMINISTIC.
This clause is optional and can only be specified once per function
definition.
See “Deterministic Characteristics Clause” on page 254.
CALLED ON NULL INPUT
that the function is always evaluated whether parameters are null at
the time the function is to be called or not.
This clause is optional and can only be specified once per function
definition.
See “Null Call Clause” on page 254
EXTERNAL
the introduction to the mandatory external function body reference
clause.
This clause can specify two different things:
• The keyword EXTERNAL only.
• The keywords EXTERNAL NAME plus an external function
name (with optional Parameter Style specification)
See “External Body Reference Clause” on page 255.
NAME
external_function_name
the entry point for the function object.
Case is significant and must match the C or C++ function name.
See “External Name Clause” on page 257.
SQL Reference: Data Definition Statements
285
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
NAME
external_string_literal
a string that specifies the source and object components needed to
build the function and, optionally, whether to compile the UDF C or
C++ object code with debug symbols.
Depending on the initial code in the sequence, the string specifies
either the C/C++ function object name for the UDF or an encoded
name or path for the components needed to create the function.
The following table briefly documents the codes used to specify
component locations:
IF you specify
this code …
F
THEN the …
string that follows is the entry point name of the
C or C++ function object.
See “Function Entry Name Clause” on
page 260.
C
source or object code for the function is stored
on the client and the string that follows is the
path to its location.
See “Client-Server UDF Code Specification” on
page 260.
S
source or object code for the function is stored
on the server and the string that follows is the
path to its location.
See “Client-Server UDF Code Specification” on
page 260.
286
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
NAME
external_string_literal
(continued)
The following table briefly documents the path specifications for the
external function. The character ¡ represents an arbitrary
user-defined delimiter.
You must use the same delimiter throughout the string specification.
File Type
Function object
Syntax
F¡function_entry_point_name
See “Function Entry Name Clause” on
page 260 for details.
Include
I¡name_on_server¡include_name
See “Include Name Clause” on page 261
for details.
Library
L¡library_name
See “Library Name Clause” on page 262
for details.
Object
O¡name_on_server¡object_name
See “Object File Name Clause” on
page 262 for details.
Package
P¡package_name
See “Package Name Clause” on page 263
for details.
Source
S¡name_on_server¡source_name
See “Source File Name Clause” on
page 265 for details.
To compile the C or C++ object code with debug symbols for core
dump analysis, specify the delimited character D at any point in the
external string literal. This feature does not produce a useful .so or
.dll file with debug symbols for Linux and Windows systems.
IF you …
THEN the system compiles the UDF source
code …
specify the D option
and produces debug symbols.
Generates a core file when a protected
mode UDF crashes.
do not specify the D
option
SQL Reference: Data Definition Statements
but does not generate debug symbols.
287
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
NAME
external_string_literal
The purpose of the D option is to provide debug symbol
information for the UDF when examining a UDF core file with gdb
(see SQL Reference: UDF, UDM, and External Stored Procedure
Programming).
(continued)
See the user documentation for your C or C++ compiler and
debugger for debugging information.
A side effect of specifying the D option is that linked libraries
become larger because they must also contain all the symbol
information.
EXTERNAL SECURITY
keywords introducing the external security clause.
This clause is mandatory for external UDFs that perform operating
system I/O operations.
If you do not specify an external security clause, but the UDF being
defined performs OS I/O, then the results of that I/O are
unpredictable. The most likely outcome is crashing the database,
and perhaps crashing the entire system.
See “External Security Clause” on page 272 for information about
the EXTERNAL SECURITY clause and how it is used for UDFs.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174 for information about creating authorizations for
external routines.
DEFINER
that the UDF runs in the client user context of the associated
security authorization object created for this purpose, which is
contained within the same database as the function.
IF you …
THEN …
specify an
authorization name
an authorization object with that name
must be defined before you can run the
function.
do not specify an
authorization name
you must define a default DEFINER
authorization object.
The default authorization object must be
defined before a user can run the
function.
The system reports a warning if the specified authorization name
does not exist at the time the UDF is created, stating that no
authorization name exists.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174.
authorization_name
an optional authorization name.
The specified authorization object must already be defined (see
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174 for further information) or the system reports an error.
288
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Syntax element …
Specifies …
INVOKER
that the function runs in the OS user context with the associated
default authorization object that exists for this purpose.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174.
PARAMETER STYLE
See “PARAMETER STYLE” on page 228.
If you do not specify a parameter style at this point, you can specify
one after you specify a language clause and an SQL data access
clause.
You cannot specify parameter styles more than once in the same
CREATE/REPLACE FUNCTION statement.
ANSI Compliance
CREATE FUNCTION (Table Form) is compliant with the ANSI SQL-2003 standard.
Authorization
You must have explicit CREATE FUNCTION privileges on the database in which the table
function is to be contained to perform the CREATE FUNCTION statement.
The system does not grant the CREATE FUNCTION privilege automatically when you create
a database or user: you must grant that privilege explicitly.
CREATE FUNCTION is not granted implicitly on the databases and functions owned by a
database or user unless the owner also has an explicit WITH GRANT OPTION privilege
defined for itself.
Privileges Granted Automatically
The following privileges are granted automatically to the creator of a table function:
•
DROP FUNCTION
•
EXECUTE FUNCTION
Relationship Among UDFs, Table UDFs, and External Stored Procedures.
UDFs, table UDFs, methods, and external stored procedures are specific variations of one
another and share most properties in common. See “CREATE FUNCTION/ REPLACE
FUNCTION” on page 222 and “CREATE PROCEDURE (External Form)/ REPLACE
PROCEDURE (External Form)” on page 463.
SQL Reference: Data Definition Statements
289
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Definition: Table Function
A table function is a user-defined function that returns a multirow relational table, one row at
a time to the SELECT statement that calls it. You define the structure of the table to be
returned in one of two ways:
•
If you know the number of columns that will be returned before you run the function,
then you define the return table structure similarly to the way you define the structure of a
persistent table using the CREATE TABLE statement (see “CREATE TABLE” on page 648),
by specifying its component column names and their respective data types.
The complete set of column names and their accompanying data types defines the
structure of the table the function returns to the caller.
You must define at least one column name and its data type for any table function
definition.
If one of the specified columns has a LOB data type, then you must define at least one
other non-LOB column.
Each column name is limited to a maximum of 30 characters, with the same restrictions as
other object identifiers (see SQL Reference: Fundamentals).
•
If you do not know the number of columns that will be returned before you run the
function, then you define the return table structure using the TABLE VARYING
COLUMNS clause and specify a maximum acceptable number of output columns to be
returned. The system stops building return table columns if the specified limit is reached.
See “Example 8: Dynamic Result Row Specification” on page 301 for an example of how to
create and use a dynamic row result table function.
The maximum number of columns you can specify is 2,048 for both the static and dynamic
forms of table function.
The returned table is derived from an external source, typically a native operating system file,
message queue, or input argument such as a LOB, and is semantically similar to a derived table
(see SQL Reference: Data Manipulation Statements).
Table functions are different from non-table UDFs because they return an entire table to the
calling statement, while a non-table UDF returns only a single scalar result.
Typical Uses for Table Functions
The most common use for table functions is to analyze non-relational data or to convert
non-relational data to relational data. Possible applications include the following:
•
Converting flat file data into relational tables.
•
Converting XML and web data into relational tables.
•
Analyzing spreadsheet data or converting it into relational tables.
Very informally, you can think of table functions as a facility for creating a view-like
mechanism that allows various SQL processing facilities to process and analyze numerous
types of non-relational data.
290
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
General Limitations and Restrictions on Table Functions
The following general restrictions apply to table functions:
•
You should always run in protected mode if a table function accesses data external to the
Teradata Database or causes the OS to consume system resources.16
You can expand the number of protected mode servers for table functions from the default
value of 2 to a maximum of 20 per AMP or PE vprocs (see the cufconfig utility in Utilities
and SQL Reference: UDF, UDM, and External Stored Procedure Programming for details).
The minimum is 0.
Protected mode servers consume disk resources as follows:
Amount of disk used = ( 256 Kbytes ) ( number of vprocs ) ( number of protected mode servers )
•
For functions running in protected mode, you need at least one protected mode server for
each table function you want to run concurrently from separate sessions (see the cufconfig
utility in Utilities and SQL Reference: UDF, UDM, and External Stored Procedure
Programming for details). A table function reserves one protected mode UDF server per
vproc for the duration of the table function step.
•
A table function can be deadlocked if too few protected mode servers are configured.
The system neither detects nor reports such a deadlock.
•
You cannot specify more than one table UDF in a FROM clause.
•
You cannot use table functions in a join condition within a FROM clause.
•
You cannot create or replace a table function from an embedded SQL application.
•
A table function cannot reference a recursive view.
•
You cannot reference a column having a UDT type.
•
The size of any row returned by a table function cannot exceed the system limit.
If a row does exceed this limit, the system aborts the request in Teradata session mode or
its containing transaction in ANSI session mode, rolls it back, and returns an error
message to the requestor.
The system defers the maximum row size check until you invoke the function because it
cannot know whether the limit will be exceeded by a table function defined with dynamic
result rows until the function runs.
•
The maximum number of columns that can be returned by any table function is 2,048.
•
When you run in protected mode, all instances of a table function run as tdatuser.
•
You must troubleshoot code problems outside the Teradata Database.
Note that you can do a limited amount of code checking by building the trace facility (see
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303) into the code with the
FNC_Trace_Write or FNC_Trace_Write_DL library calls (see SQL Reference: UDF, UDM,
and External Stored Procedure Programming for details of these library calls and other
troubleshooting methods you can build into table functions).
16. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
SQL Reference: Data Definition Statements
291
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
•
The mandatory way you must specify columns having a BLOB or CLOB data type depends
on whether you are specifying a data type for a parameter column or for a RETURN
TABLE clause column.
IF you are specifying a LOB data type in this clause …
THEN you must specify the LOB type …
parameter
with an AS LOCATOR phrase.
RETURNS TABLE
without an AS LOCATOR phrase.
Protected and Unprotected Modes
See “Protected and Unprotected Execution Modes” on page 240 for information about when
you should or should not run UDFs in protected mode.
Handling SQL Result Codes
See “How UDFs Handle SQL Result Codes” on page 241 for information about how UDFs
handle SQL result codes.
Mandatory Function Attributes
See “Mandatory Function Attributes” on page 242 for information about the mandatory
attributes for a UDF. Note that return value data types do not apply to table UDFs.
Table UDFs and Large Objects
See “User-Defined Functions and Large Objects” on page 243 for information about how
UDFs deal with large objects.
Function Names
See “Function Name” on page 245 and “Function Name Overloading” on page 247 for
information about function names.
Parameter Names and Data Types
See “Parameter Names and Data Types” on page 249 for information about parameter names
and data types.
Note that unlike the case for the RETURNS TABLE clause, you must stipulate an AS
LOCATOR phrase for any LOB parameter data types you specify in the parameters clause of a
table function.
292
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
RETURNS TABLE Clause
The basic RETURNS TABLE clause for a table UDF definition is a basic definition for the table
to be returned and consists only of a list of the columns and their respective data types.
The dynamic results row specification RETURNS TABLE clause for a table UDF definition
provides a method for dynamically defining the number of rows returned by the function
when that number cannot be known before you invoke the function. The only parameter you
specify for this clause is the maximum number of output columns. The system defines the
column names and data types at run time.
Note that unlike the case for the parameters clause, you cannot stipulate an AS LOCATOR
phrase for any LOB column data types you specify in the RETURNS TABLE clause of a table
function.
Language Clause
See “Language Clause” on page 250 for information about the LANGUAGE clause.
SQL Data Access Clause
See “SQL Data Access Clause” on page 251 for information about the SQL Data Access clause.
Optional Function Characteristics
See “Optional Function Characteristics” on page 251 for information about the optional
function characteristics. Note that table functions do not support the specification of the
RETURNS NULL ON NULL INPUT option.
Specific Function Name Clause
See “Specific Function Name Clause” on page 251 for information about the Specific
Function Name Clause.
Parameter Style Clause
See “Parameter Style Clause” on page 253 for information about the parameter style clause.
Note that the only valid parameter style for table functions is SQL.
Deterministic Characteristics Clause
See “Deterministic Characteristics Clause” on page 254 for information about the
Deterministic Characteristics clause.
Null Call Clause
See “Null Call Clause” on page 254 for information about the Null Call clause. Note that the
only form of null call supported by table functions is CALLED ON NULL INPUT.
SQL Reference: Data Definition Statements
293
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
External Body Reference Clause
See the following for information about the components of the External Body Reference
clause:
•
“External Body Reference Clause” on page 255
•
“External Name Clause” on page 257
•
“External String Literal” on page 258
•
“Function Entry Name Clause” on page 260
•
“Client-Server UDF Code Specification” on page 260
•
“Include Name Clause” on page 261
•
“Library Name Clause” on page 262
•
“Object File Name Clause” on page 262
•
“Package Name Clause” on page 263
•
“Source File Name Clause” on page 265
Table UDF Default Location Paths
See “UDF Default Location Paths” on page 269 for information about the default location of
UDF-related information.
Table UDF .so and .dll Linkage Information
See “UDF .so and .dll Linkage Information” on page 271 for information about .so and
.dll files for table UDFs.
Restrictions on Calling Table Functions
You can only call a table function in the FROM clause of an SQL SELECT statement (see SQL
Reference: Data Manipulation Statements), which includes calling table functions in the FROM
clause of a subquery. Calling a table function from any other clause within a query causes the
system to abort the request and returns an error to the requestor.
Restrictions on Declaring an External C++ Table Function
If you specify CPP in the LANGUAGE CLAUSE, then you must declare the main C++
function as extern “C” to ensure that the function name is not converted to an overloaded
C++ name. For example:
extern “C”
void my_cpp(long int *input_int, long int *result, char sqlstate[6])
{
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for details.
Example 1
This example takes variable input arguments based on input from a previous correlated
subquery in the FROM clause of a SELECT statement, which is not shown. The function
294
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
definition inputs XML text, which it then parses to extract a customer ID, store number, and
the set of items purchased. The output produces one row per item purchased, with the
columns being based on existing columns in the table defined in the function definition.
CREATE FUNCTION xml_extract( xml_text VARCHAR(64000))
RETURNS TABLE (cust_id INTEGER,
store
INTEGER,
item
INTEGER)
LANGUAGE C
NO SQL
EXTERNAL;
Example 2
Assume you have the following table function definition:
CREATE FUNCTION xml_extract( xml_text LOCATOR CLOB)
RETURNS TABLE (cust_id INTEGER,
store
INTEGER,
item
INTEGER)
LANGUAGE C
NO SQL
EXTERNAL;
This function extracts all items from the CLOB xml_text that have been ordered from a
particular store by a particular customer by means of a web application. It then produces one
result row for each item ordered.
The XML data is already in a database table with the following table definition:
CREATE TABLE xml_tbl (
store_no INTEGER,
refnum
INTEGER,
xml_store_text CLOB)
UNIQUE PRIMARY INDEX (store_no, refnum);
Here are the assumptions underlying the analysis of the XML data by means of the
xml_extract table function:
•
Table xml_tbl contains the following columns:
•
A store number column named store_no.
•
A reference number column named refnum.
•
An XML text column named xml_store_text.
•
The xml_store_text column contains the XML-formatted text for customers who ordered
web-based items from the store.
•
Each XML text data column contains information for the customer who placed the order
as well as the items that customer ordered.
The purpose of the table function is to extract all items the customer ordered from the XML
document. One XML row is created for each order placed by the online web-based system.
Because the XML text could consist of several items, a table function is the natural approach
to extracting the data, with one row being extracted for each item ordered. If there were 10
items in the XML text, then the table function would return a 10-row table.
SQL Reference: Data Definition Statements
295
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
The following SELECT request shows a possible application for the xml_extract table function:
SELECT l.customer_id l.store, l.item,
FROM (SELECT xml_store_text
FROM xml_tbl AS x
WHERE store_no = 25), TABLE(xml_extract(x.xml_text_store))
AS l (cust_id,store,item);
This SELECT request produces one row for each item bought by all customers from store 25.
Its first derived table produces the XML test field from all rows with a store number of 25. The
second derived table is the result of evaluating table function xml_extract.
Aside
This query specifies two tables in the FROM clause: table x and table l, where table l is the
result of the table function. The qualifying rows of the xml_tbl aliased as x are combined as a
Cartesian Product with the rows produced by the table function as table l. This is probably not
the desired result.17
You can rewrite this query to return just the distinct rows as follows:
SELECT DISTINCT l.customer_id l.store, l.item,
FROM (SELECT xml_store_text
FROM xml_tbl AS x
WHERE store_no = 25), TABLE(xml_extract(x.xml_store_text))
AS l;
End of Aside
The logical process followed by the original SELECT operation is as follows:
1
Create the first derived table from the first subquery in the FROM clause with the table
correlation name x.
2
Evaluate the table function.
The function has an input argument that references column x.xml_text_store from the
derived table. This means that the database must invoke the table function repeatedly in a
loop for each row produced by table x. The loop ends when the table function returns with
the "no more data" message.
17. It is also true that the process used to achieve the result is not quite what the ANSI SQL:2003 standard
specifies, because the subquery is processed as a noncorrelated subquery, while the ANSI standard
requires it to be processed as a correlated subquery.
296
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
The process followed by the loop is as follows:
a
Read a row for table x where store_no = 25.
b
Determine whether such a row is found.
IF a matching row is …
THEN …
found
continue processing.
not found
stop processing.
c
Call the table function xml_extract(x.xml_text_store).
d
Determine whether there is more data to process.
IF the call …
THEN …
does not return with a SQLSTATE code of ‘02000’
(no more data)
continue processing.
returns with a SQLSTATE code of ‘02000’
go to Stage g.
e
Write the new row produced by the xml_extract table function.
f
Go to Stage c.
g
End of process.
3
Return results to requestor.
4
End of process.
To elaborate further from yet another perspective, Teradata Database undertakes the following
process when solving this problem:
1
The system passes the x.xml_text_store result produced by the derived table SELECT
request as input to the table function xml_extract.
2
The system invokes the table function repeatedly for the same row.
Each time the table function is called, it produces one row containing the cust_id, store,
and item columns.
3
When the table function has exhausted everything from that xml_text_store CLOB, it
returns with an SQLSTATE of “no data” (‘02000’).
4
This “no more data” result causes the system to read the next row produced by the first
derived table.
5
The system repeats the process for another customer, generating more rows for the next
xml_text_store.
6
End of process.
SQL Reference: Data Definition Statements
297
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Example 3: Constant Reference Table Function
This example shows a constant reference table function equijoined to another table.
Note the following things about this example:
•
The table function is sent to all AMPs with the same constant data; therefore, it is a
constant mode table function (see TABLE_MODE_CONST in SQL Reference: UDF, UDM,
and External Stored Procedure Programming)
•
The table function tudf1 produce all the rows selected.
After that, the WHERE condition selects a subset from those produced. Only the
qualifying rows are returned to the requestor.
SELECT *
FROM tbl_1, TABLE(tudf1(28.8, 109)) AS tf2
WHERE tbl_1.c1 = tf2.c1;
Example 4: Variable Reference Table Function
This example shows a variable reference table function equijoined to another table.
Note the following things about this example:
•
The table function is sent to all AMPs and is passed tbl.c1 from all rows in tbl1; therefore it
is a variable mode table function (see TABLE_MODE_VARY in SQL Reference: UDF,
UDM, and External Stored Procedure Programming).
•
The designer of this table function added a third argument to demonstrate that the
function can provide some intelligence by not producing any rows unless the condition
“equal” is met. For example, if the input argument tbl_l.c1 and the row for value tf2.c1 are
not equal, the function does not produce any rows. This code eliminates the need for a
subsequent step to filter rows produced by the table function resulting from the WHERE
clause condition.
SELECT *
FROM tbl_1, TABLE(tudf1(28.8, tbl_1.c1, ‘equal’)) AS tf2
WHERE tbl_1.c1 = tf2.c1;
Example 5: Variable Reference Table Function Called From a Derived Table
This example shows a variable reference table function (see TABLE_MODE_VARY in SQL
Reference: UDF, UDM, and External Stored Procedure Programming) equijoined to a derived
table.
The derived table dt1 is created first as a subset of tbl1, then a column dt1.c1 for each row is
passed to the table function. The resultant rows of the table function are combined with the
selected rows of the derived table by means of the WHERE condition.
The relevant function definition is as follows:
CREATE FUNCTION tudf1 (FLOAT, INTEGER, INTEGER)
RETURN TABLE (
c1 DECIMAL,
c2 INTEGER,
c3 INTEGER)
… ;
298
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
The SELECT request that uses this table function is as follows:
SELECT dt1.c1, tf2.c2, tf2.c3
FROM (SELECT c1, c2
FROM tbl1
WHERE c1 < 500) AS dt1,
TABLE (tudf1(45.6, 193, dt1.c1)) AS tf2 (nc1, nc2, nc3)
WHERE dt1.c1 = tf2.nc1);
Example 6:
If you are running a dual active Teradata system, or if you have a second Teradata system for a
development or test machine, there might be times when you would need to pass data
between the two platforms. For example, it might be useful to query the dictionary tables from
one system so they can be correlated with the other. This example illustrates how you might
do that.
The following SELECT statement uses a table function named tdat that executes a query on a
remote Teradata system and then returns the answer set to the requesting system. In this
example, the UDF returns all the database names in the dictionary tables of the other system.
SELECT *
FROM table(rdg.tdat(2,1,'adw1/rdg,rdg', 'SELECT databasename FROM
dbc.databases'));
This SELECT statement is passed as a fixed input argument of the table function from the
requesting system and is executed on the target system, as is the logon string for that system.
The DDL to create the table function is as follows:
CREATE FUNCTION rdg.tdat
(rowc
INTEGER,
InLineNum INTEGER,
logonstr
VARCHAR(50)
CHARACTER SET LATIN,
sqlRqst
VARCHAR(512) CHARACTER SET LATIN)
RETURNS TABLE (
ampId
INTEGER,
cnt
INTEGER,
OutLineNum INTEGER,
str1
VARCHAR(256) CHARACTER SET LATIN,
.
.
.
str20
VARCHAR(256) CHARACTER SET LATIN)
SPECIFIC tdat
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
NOT DETERMINISTIC
CALLED ON NULL INPUT
EXTERNAL NAME 'SS:tdat:/home/rdg/tdat/Tdat.c:SL:cliv2';
By creating a view across two Teradata systems you can compare dictionary content across
both platforms and compare detailed data such as table space or access rights.
SQL Reference: Data Definition Statements
299
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
The following view compares the rows that appear in the DBC.Tables view of each system:
CREATE VIEW allTables AS
SELECT 'Local System' AS system, databasename, tablename, version,
tablekind, protectionType, JournalFlag, CreatorName,
requesttext(VARCHAR(100))
FROM DBC.tables
UNION
SELECT 'Remote System', str1 (CHAR(30)), str2 (CHAR(30)),
str3 (INTEGER), str4 (CHAR(1)), str5 (CHAR(1)),
str6 (CHAR(2)), str7 (CHAR(30)), str8 (VARCHAR(100))
FROM table(rdg.tdat(2,1,'adw1/rdg,rdg', 'SELECT databasename,
tablename, version, tablekind, protectionType,
JournalFlag, CreatorName, requesttext(VARCHAR(100))
FROM DBC.tables')) T;
A sampling of data returned from the remotely performed SELECT query, when ordered by
tablename (for easy cross comparison, looks like this:
System
-------------Remote System
Local System
Remote System
Remote System
Local System
Local System
Remote System
DatabaseName
-----------test
DBC
DBC
DBC
DBC
rdg
test
TableName
-----------a
AccessRights
AccessRights
AllSpace
AllSpace
allamp
allamp
Version
------1
1
1
1
1
1
1
TableKind
--------T
T
T
V
V
T
T
Example 7: Different LOB Specifications for Parameter and RETURNS
TABLE Clauses
The following example indicates the different ways you must specify LOB data types for
function parameters and table columns, respectively. Notice how the parameter type
specifications require the specification of an AS LOCATOR phrase, while the table column
specifications prohibit the use of an AS LOCATOR phrase.
CREATE FUNCTION lobtf_concat3 (
NumRows INTEGER,
A
BLOB AS LOCATOR,
B
VARBYTE(64000),
C
BLOB AS LOCATOR)
RETURNS TABLE (AmpNum
INTEGER,
A_OUT
BLOB(10),
B_OUT
VARBYTE(10),
C_OUT
BLOB(10),
MyResult
BLOB(30))
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME 'SS!lobtf_concat3!/home/i18n/hsf/tf/c/
lobtf_concat3.c';
300
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
Example 8: Dynamic Result Row Specification
The following example defines a table function named extract_store_data that has variable
output columns.
The SELECT request following the function definition uses extract_store_data to parse the
input text string and extract store sales data into the store_data table.
CREATE FUNCTION extract_store_data (
text
VARCHAR(32000),
from_store INTEGER)
RETURNS TABLE VARYING COLUMNS (10)
SPECIFIC extract_store_data
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
NOT DETERMINISTIC
EXTERNAL NAME 'SS!extract_store_data!extract_store_data.c';
INSERT INTO store_data
SELECT *
FROM (TABLE(extract_store_data('…', 1000)
RETURNS store_data) AS store_sales;
Example 9: Running a Table Function With a Dynamic Result Row
Specification and Loading the Resulting Data Into a Base Data Table
The following example shows a table function being called from a SELECT request to return a
set of rows from an external source. The function is defined with a maximum number of 256
output parameters.
CREATE FUNCTION sales_retrieve(store_no INTEGER)
RETURNS TABLE VARYING COLUMNS (256)
LANGUAGE C
NO SQL
PARAMETER STYLE SQL
EXTERNAL NAME '...';
The sales_retrieve function reads some data from an external source and produce rows based
on the data it reads.
Both of the following INSERT … SELECT requests accomplish the job of inserting all rows
produced by sales_retrieve into the table named sales_table, which is defined as follows:
CREATE TABLE sales_table (
store
INTEGER,
item
INTEGER,
quantity INTEGER);
SQL Reference: Data Definition Statements
301
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE FUNCTION (Table Form)
The following requests are equivalent INSERT … SELECT requests for loading the output of
sales_retrieve into sales_table:
INSERT INTO sales_table
SELECT *
FROM TABLE (sales_retrieve(9005)
RETURNS (store
INTEGER,
item
INTEGER,
quantity INTEGER)) AS s;
INSERT INTO sales_table
SELECT *
FROM TABLE (sales_retrieve(9005)
RETURNS sales_table) AS s;
Related Topics
See the following for information related to table functions:
302
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174 for
information about creating external authorization objects.
•
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222 for usage notes about the
UDF clauses that are not fully explained here.
•
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303.
•
“DROP AUTHORIZATION” on page 1001
•
SQL Reference: UDF, UDM, and External Stored Procedure Programming for information
about coding table functions.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
CREATE GLOBAL TEMPORARY TRACE TABLE
Purpose
Creates a global temporary trace table to support the UDF- and external stored
procedure-related trace option of the SET SESSION statement (see “SET SESSION
FUNCTION TRACE” on page 1162).
Syntax
A
table_name
CREATE GLOBAL TEMPORARY TRACE TABLE
database_name.
A
( proc_ID BYTE(2)
,
sequence INTEGER
(
,
column_name
data
type
declaration
B
data
type
attributes
B
ON COMMIT
DELETE
ROWS
;
PRESERVE
1101A534
SQL Reference: Data Definition Statements
303
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Data Type Declarations
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
WITH TIMEZONE
TIMESTAMP
WITH TIMEZONE
INTERVAL YEAR
TO MONTH
INTERVAL MONTH
INTERVAL DAY
TO HOUR
TO MINUTE
TO SECOND
INTERVAL HOUR
TO MINUTE
TO SECOND
INTERVAL MINUTE
TO SECOND
INTERVAL SECOND
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
CHAR
BYTES
( integer )
GRAPHIC
VARCHAR
( integer )
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
1101A397
304
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Data Type Attributes
NOT NULL
UPPERCASE
UC
CASESPECIFIC
NOT
CS
FORMAT
quotestring
TITLE
quotestring
NAMED
name
CHARACTER SET
server_character_set
1101B115
where:
Syntax element …
Specifies …
database_name
the name of the database in which table_name is to be contained if
something other than the current database.
table_name
the name of the new table.
If the name is not fully qualified, then the system assigns the name of the
default database for the current session.
proc_ID BYTE(2)
the mandatory first column and data type for all global temporary trace
tables.
This column records the number of the AMP on which the UDF that wrote
the row is running.
The column can have any name, but it must be declared as BYTE(2).
sequence INTEGER
the mandatory second column and data type for all global temporary trace
tables.
This column records a sequence number to indicate the order in which the
function trace rows in the table were written for the logged AMP.
The column can have any name, but it must be declared as INTEGER.
column_name
SQL Reference: Data Definition Statements
specifies the name of one or more optional columns, in the order in which
they and their attributes are to be defined for the table. Up to 2,048
columns can be defined for a table.
305
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Syntax element …
Specifies …
data_type_declaration
data_type_attributes
one or more data definition phrases that define data for the column.
You must specify a single data type for each column_name.
You cannot specify a UDT type for any column in a global temporary trace
table. You can dump all the predefined attributes of a UDT into a trace table
using FNC calls, however (see SQL Reference: UDF, UDM, and External
Stored Procedure Programming for information about how to use FNC
calls).
You cannot write Java strings into a global temporary trace table column
defined with any of the following data types because the Java language does
not support the types:
• GRAPHIC
• VARGRAPHIC
• LONG GRAPHIC
Column data type attribute specifications are optional. If you specify
attributes for a column, you should define its data type prior to defining the
attributes.
The only valid constraints for global temporary trace table columns are
NULL and NOT NULL.
If you specify NOT NULL, but the UDF does not return data, then that
column is padded with appropriate values, depending on the data type.
You cannot specify DEFAULT or WITH DEFAULT column attributes for
global temporary trace table columns.
If you do not specify explicit formatting, a column assumes the default
format for the data type, which can be specified by a custom data
formatting specification (SDF) defined by the tdlocaledef utility (see
Utilities). Explicit formatting applies both to the parsing and to the retrieval
of character strings.
Data types and data type attributes are the subject of SQL Reference: Data
Types and Literals.
ON COMMIT
PRESERVE/DELETE
ROWS
to delete or preserve the contents of a global temporary or volatile table
when a transaction completes.
DELETE is the default.
ANSI Compliance
Global temporary trace tables are a Teradata extension to the ANSI SQL-2003 standard
definition of global temporary tables.
306
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Authorization
You must have the CREATE TABLE privilege on the database in which the table is created.
The creator receives all the following privileges on the newly created table:
• DROP TEMPORARY TABLE
• DUMP
• REFERENCE
• RESTORE
• SELECT
Privileges Granted Automatically
None.
Global Temporary Trace Tables
Like global temporary tables, global temporary trace tables have a persistent definition, but do
not retain rows across sessions.
Global temporary trace tables are not hashed. Instead, each table row is assigned a sequential
hash sequence. You can perform an INSERT … SELECT operation on the table to copy its
rows into a normal hashed table with a primary key, indexes, or additional attributes common
to other base table types if you need to do so.
Define the information you want to trace as the input to the UDF. The UDF can then call the
FNC_Trace_Write_DL function (see SQL Reference: UDF, UDM, and External Stored
Procedure Programming) that places the information in a global temporary trace table. If the
trace is not turned on (see “SET SESSION FUNCTION TRACE” on page 1162), the system
does no function traceback, though there is still some overhead because the system still calls
the UDF.
Make sure to run the trace UDF in nonprotected mode once it has been debugged to ensure
that it executes in-line with the procedure. A premature end of the procedure or a rollback of
the transaction has no impact on the global temporary trace table, and its contents are not
deleted until the session logs off. Enabling function traceback makes your procedure run more
slowly because each trace call forces the data to be written into the trace table. Nothing is
buffered to ensure that nothing is lost while you are testing a function. See “Example 3:
Complete Function Traceback Scenario” on page 310 for a complete example on how to use a
global temporary trace table to do function traceback.
SQL Reference: Data Definition Statements
307
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Rules and Limitations for Global Temporary Trace Tables
Because global temporary trace tables are not hashed, they have many definition and
manipulation restrictions that distinguish them from ordinary global temporary tables (see
“Global Temporary Tables” on page 674).
The following rules and limitations apply to global temporary trace tables:
•
You cannot define them as set tables. All global temporary trace tables are restricted to the
multiset table type.
•
You cannot specify fallback characteristics for a global temporary trace table. They are
always created as NO FALLBACK by default.
If you specify FALLBACK, the system returns an error.
•
You cannot define a primary key for the table.
•
You cannot define any indexes on the table, including a primary index.18
•
You cannot define any column in the table with a BLOB or CLOB data type.
•
You cannot define any columns with a UDT type.
To get around this, you can use FNC calls to dump the predefined attributes of a UDT into
non-UDT columns of the trace table. See SQL Reference: UDF, UDM, and External Stored
Procedure Programming for information about using FNC calls.
•
You cannot specify any column constraints other than NULL and NOT NULL.
•
You cannot specify default column values for the table.
•
The first two columns of the table must be defined as follows, in the order indicated:
•
BYTE(2)
This column records the number of the AMP on which the logged UDF is running.
•
INTEGER
This column records a sequence number that describes the order in which the function
trace row was generated.
Any other columns are optional and user-defined.
•
If you try to use the same trace table to simultaneously trace a UDF that runs on an AMP
and an external stored procedure or UDF that runs on a PE, the sequence number written
to the second column is not in true sequential order. This is because the AMP bases the
next sequence number on the sequence of the last row of the trace table and adds one to it
no matter where the row originated.
The rows inserted into the trace table from the PE are hashed to one AMP based on the PE
vproc number and the current sequence number. Therefore, if the current sequence
number for the PE is 5 and the trace row is added to AMP 1, then a trace write into that
table from AMP 1 has the sequence number 6.
The best practice is to avoid simultaneously tracing on an AMP and PE.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for more
information.
18. This restriction explicitly includes both partitioned and nonpartitioned primary indexes.
308
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
•
If you specify ON COMMIT PRESERVE ROWS, then the system preserves the rows of the
materialized trace table after the transaction commits or after it aborts; otherwise, all rows
are deleted from the table.
If the trace table was materialized for the session by the transaction that aborts, it is
deleted, so in that case, no rows are preserved. Once the trace table is successfully
materialized, however, the system retains any rows a UDF had written to it before the abort
occurred.
•
You cannot join a global temporary trace table with another table.
•
You cannot update a global temporary trace table. In other words, you cannot perform
DELETE, INSERT, or UPDATE statements against a global temporary trace table, though
you can specify DELETE ALL.
•
You can INSERT … SELECT from a global temporary trace table into another table.
•
You can select the contents of the trace table for output to a response spool file for
examination.
The SELECT statement used for this purpose can specify a WHERE clause to determine
the criteria used to select the rows. It can also specify an ORDER BY clause.
•
You can perform DROP TEMPORARY TABLE on a global temporary trace table.
•
Because there is no primary index, all requests that are normally primary index retrievals
are, instead, full-table scans.
Example 1
This example defines the mandatory columns for a global temporary trace table as well as
several optional, application-specific, columns. When the transaction that materializes
udf_test commits, its contents are to be deleted.
CREATE GLOBAL TEMPORARY TRACE TABLE udf_test
(proc_ID
BYTE(2),
sequence
INTEGER,
udf_name
CHARACTER(15),
in_quantity INTEGER,
trace_val1
FLOAT,
trace_text
CHARACTER(30))
ON COMMIT DELETE ROWS;
A simple query to retrieve the results recorded in udf_test might look like this:
SELECT *
FROM udf_test
ORDER BY proc_id ASC, sequence ASC;
SQL Reference: Data Definition Statements
309
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Example 2
The following example defines a simple trace table that has a single column variable length
string to capture function output.
This single VARCHAR column approach lends itself to a flexible trace output that can be used
by many different functions without having to resort to specific single-purpose trace table
column definitions.
CREATE GLOBAL TEMPORARY TRACE TABLE udf_test, NO LOG
(proc_ID
BYTE(2),
sequence
INTEGER,
trace_string VARCHAR(256))
ON COMMIT DELETE ROWS;
Example 3: Complete Function Traceback Scenario
The following simple stored procedure trace example is a complete scenario that shows the
various aspects of using global temporary trace tables to debug a procedure.
The following CREATE FUNCTION request, returned by a SHOW FUNCTION request
submitting using BTEQ, defines the traceback UDF that was used for this example. You can
make the procedure as simple, or as complex, as your application requires. This particular
trace UDF is fairly simple.
SHOW FUNCTION sptrace;
*** Text of DDL statement returned.
*** Total elapsed time was 1 second.
-----------------------------------------------------------------CREATE FUNCTION sptrace (
p1 VARCHAR(100) CHARACTER SET LATIN)
RETURNS INTEGER
SPECIFIC sptrace
LANGUAGE C
NO SQL
PARAMETER STYLE TD_GENERAL
NOT DETERMINISTIC
RETURNS NULL ON NULL INPUT
EXTERNAL NAME sptrace
*** Text of DDL statement returned.
-----------------------------------------------------------------#define SQL_TEXT Latin_Text
#include <sqltypes_td.h>
/*
Install in SYSLIB for general use and change to NOT PROTECTED mode
ALTER FUNCTION sptrace EXECUTE NOT PROTECTED;
*/
/* Assumes that the following trace table has been created */
/*
310
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
CREATE MULTISET GLOBAL TEMPORARY TRACE TABLE tracetst,
NO FALLBACK, NO LOG (
proc_id
BYTE(2),
sequence INTEGER,
trace_str VARCHAR(100))
ON COMMIT PRESERVE ROWS;
Turn on tracing with following SQL (decide what your options mean):
SET SESSION FUNCTION TRACE USING 'T' FOR TABLE tracetst;
*/
void sptrace(VARCHAR_LATIN
*trace_text,
INTEGER
*result,
char
sqlstate[6])
{
SQL_TEXT
trace_string[257];
void
*argv[20]; /* only need 1 arg -- its an array */
int
length[20]; /* one length for each argument */
int
tracelen;
/* read trace string */
FNC_Trace_String(trace_string);
/* Get length of string */
tracelen = strlen(trace_string);
/* Make sure tracing is turned on */
if (tracelen == 0)
return;
if (trace_string[0] == 'T')
{
argv[0] = trace_text;
length[0] = strlen(trace_text) +1;
/* Have something to trace */
FNC_Trace_Write_DL(1, argv, length);
}
}
The following SQL text defines the stored procedure that calls the trace function sptrace.
SHOW PROCEDURE sptracedemo;
*** Text of DDL statement returned.
*** Total elapsed time was 1 second.
----------------------------------------------------------------CREATE PROCEDURE sptracedemo (
num_rows INTEGER )
BEGIN
-- Teradata mode stored procedure
DECLARE dummy INTEGER;
DECLARE start_val INTEGER;
DECLARE fnum FLOAT;
SET dummy = sptrace('Start of sptrace demo');
SQL Reference: Data Definition Statements
311
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
BEGIN
DECLARE EXIT HANDLER FOR SQLSTATE '52010'
BEGIN
-- Table already exists, delete the contents
DELETE sp_demo1 ALL;
SET dummy=sptrace('Deleted contents of sp_demo1 in handler');
-- Get error here and procedure will exit
END;
CREATE TABLE sp_demo1 (
a INTEGER,
b FLOAT);
SET dummy = sptrace('Table sp_demo1 created');
END;
SET start_val = 1;
SET fnum = 25.3;
WHILE start_val <= num_rows DO
INSERT INTO sp_demo1 (start_val, fnum);
SET dummy = sptrace('did: insert (' || start_val ||','|| fnum
||');');
SET start_val = start_val +1;
SET fnum = sqrt(fnum);
END WHILE;
SET dummy = sptrace('Got to end of sptrace demo'); END;
The remainder of the scenario constitutes the actual example.
Note that global temporary trace tables are user-defined except for first two columns, which
are always fixed.
First show the definition of the global temporary trace table, tracetst, used for this example.
SHOW TABLE tracetst;
*** Text of DDL statement returned.
*** Total elapsed time was 1 second.
------------------------------------------------------------------CREATE MULTISET GLOBAL TEMPORARY TRACE TABLE tracetst,NO FALLBACK,
CHECKSUM = DEFAULT,
NO LOG (
proc_id
BYTE(2),
sequence INTEGER,
trace_str VARCHAR(100) CHARACTER SET LATIN NOT CASESPECIFIC)
ON COMMIT PRESERVE ROWS;
The next request enables function traceback for the session (see “SET SESSION FUNCTION
TRACE” on page 1162 for additional information). The variable t is a user-defined string,
interpreted by your trace UDF, that can be up to 255 characters long.
SET SESSION FUNCTION TRACE USING 't' FOR TABLE tracetst;
*** Set SESSION accepted.
*** Total elapsed time was 1 second.
Function traceback has been enabled for the session.
312
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Now select the contents of the global temporary trace table tracetst to ensure that it has no
rows.
SELECT *
FROM tracetst
ORDER BY 1, 2;
*** Query completed. No rows found.
*** Total elapsed time was 1 second.
The trace table is empty.
Run the trace procedure sptracedemo, whose definition is indicated by the SHOW
PROCEDURE request at the end of this example:
CALL sptracedemo(3);
*** Procedure has been executed.
*** Total elapsed time was 1 second.
Select the contents of your global temporary trace table tracetst after the procedure executes.
Refer to the stored procedure definition to see exactly what it traces.
SELECT *
FROM tracetst
ORDER BY 1, 2;
*** Query completed. 6 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
proc_id Sequence trace_str
------- ---------------------------------------------------------FF3F
1 Start of sptrace demo
FF3F
2 Table sp_demo1 created
FF3F
3 did: insert (
1, 2.53000000000000E 001);
FF3F
4 did: insert (
2, 5.02991053598372E 000);
FF3F
5 did: insert (
3, 2.24274620409526E 000);
FF3F
6 Got to end of sptrace demo
Now call sptracedemo again.
CALL sptracedemo(3);
*** Procedure has been executed.
*** Total elapsed time was 1 second.
Select the contents of the global temporary trace table again. Note that it takes a different path
because the global temporary trace table has already been populated with rows this time.
SELECT *
FROM tracetst
ORDER BY 1, 2;
*** Query completed. 12 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
SQL Reference: Data Definition Statements
313
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
proc_id
------FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
Sequence trace_str
--------------------------------------------------------1 Start of sptrace demo
2 Table sp_demo1 created
3 did: insert (
1, 2.53000000000000E 001);
4 did: insert (
2, 5.02991053598372E 000);
5 did: insert (
3, 2.24274620409526E 000);
6 Got to end of sptrace demo
7 Start of sptrace demo
8 deleted contents of sp_demo1 in handler
9 did: insert (
1, 2.53000000000000E 001);
10 did: insert (
2, 5.02991053598372E 000);
11 did: insert (
3, 2.24274620409526E 000);
12 Got to end of sptrace demo
Disable function traceback to show that nothing additional is written to the trace table when
the procedure is called, but function traceback is not enabled.
SET SESSION FUNCTION TRACE OFF;
*** Set SESSION accepted.
*** Total elapsed time was 1 second.
CALL sptracedemo(3);
*** Procedure has been executed.
*** Total elapsed time was 1 second.
SELECT *
FROM tracetst
ORDER BY 1, 2;
*** Query completed. 12 rows found. 3 columns returned.
*** Total elapsed time was 1 second.
proc_id
------FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
FF3F
Sequence trace_str
--------------------------------------------------------1 Start of sptrace demo
2 Table sp_demo1 created
3 did: insert (
1, 2.53000000000000E 001);
4 did: insert (
2, 5.02991053598372E 000);
5 did: insert (
3, 2.24274620409526E 000);
6 Got to end of sptrace demo
7 Start of sptrace demo
8 deleted contents of sp_demo1 in handler
9 did: insert (
1, 2.53000000000000E 001);
10 did: insert (
2, 5.02991053598372E 000);
11 did: insert (
3, 2.24274620409526E 000);
12 Got to end of sptrace demo
The identical 12 rows are selected from tracetst, so function traceback was successfully
disabled.
314
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE GLOBAL TEMPORARY TRACE TABLE
Related Topics
See “SET SESSION FUNCTION TRACE” on page 1162 for information about enabling
function traceback.
Also see “Global Temporary Tables” on page 674 and “Volatile and Global Temporary Tables,
Teradata Session Mode, and DML Performance” on page 675 for general information about
global temporary tables and SQL Reference: UDF, UDM, and External Stored Procedure
Programming for information about coding external functions.
SQL Reference: Data Definition Statements
315
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
CREATE HASH INDEX
Purpose
Creates a new hash index on a base table.
Syntax
A
hash_index_name
CREATE HASH INDEX
database_name.
A
B
,
,
FALLBACK
NO
PROTECTION
CHECKSUM = integrity_checking_level
,
B
( column_name_1
) ON
table_name
C
,
BY
(
column_name_2
)
C
ORDER BY
;
VALUES
(
HASH
column_name_3
,
(
column_name_3
)
(
column_name_3
)
)
1101A431
where:
Syntax element …
Specifies …
database_name
the name of the database that will contain hash_index_name if other than
the current database.
hash_index_name
the name given to the hash index created by this statement.
Hash index names conform to the rules for naming tables, including
explicit qualification with a database or user name.
A hash index need not be defined in the same database as the base table
represented in its definition.
FALLBACK
[PROTECTION]
316
that the hash index uses fallback protection.
PROTECTION is an optional noise keyword that has no effect on the
hash index definition.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Syntax element …
Specifies …
NO FALLBACK
[PROTECTION]
that the hash index does not use fallback protection.
The default if you do not make a specification is to use the fallback
specification for the database in which the hash index is defined.
PROTECTION is an optional noise keyword that has no effect on the
hash index definition.
Note that if a hash index is not fallback protected, an AMP failure
prevents the following events from occurring:
• Processing queries on the hash index
• Updating the table on which the hash index is defined
integrity_checking_level
a table-specific disk I/O integrity checksum level.
The checksum setting applies to primary and fallback data rows for the
hash index.
If you do not specify a value, then the system assumes the system-wide
default value for this table type. The result is identical to specifying
DEFAULT.
If you are changing the checksum for this table to the system-wide default
value, then specify DEFAULT.
You can change the percentage of sampling for the system-wide default
values for LOW, MEDIUM, and HIGH using the Checksum Level
Definitions fields in the DBSControl utility (see Utilities). The values
provided here for those checksum percentages are the defaults specified
by the installation or upgrade.
You cannot change the sampling percentage for the following:
• The system-wide default values ALL and NONE.
• Dictionary tables.
The following table lists the different integrity checking levels and their
meanings:
Level
ALL
100
DEFAULT
Percentage specified for this table type in the
Checksum Levels fields of the Disk I/O Integrity
Fields in the DBSControl utility (see Utilities).
HIGH
67
MEDIUM
33
LOW
NONE
SQL Reference: Data Definition Statements
Checksum Sample Count Percentage
2
Disable checksum disk I/O integrity checks.
317
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Syntax element …
Specifies …
column_name_1
the name of a column to be contained in the hash index.
All columns defined in the column_name_1 list must be drawn from the
base table on which the hash index is defined.
No column in a hash index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a hash index.
You cannot qualify the columns in the column_name_1 list.
You cannot specify the system-derived columns PARTITION,
PARTITION#L1, PARTITION#L2, PARTITION#L3, PARTITION#L4,
PARTITION#L5, PARTITION#L6, PARTITION#L7, PARTITION#L8,
PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the
column_name_1 list.
The maximum number of columns you can specify, including the
columns implicitly added to the hash index when it is created, is 64.
Just as it does for secondary index definitions, the system extends the hash
index definition transparently with additional elements that make it
possible to provide an access path to the corresponding rows in the base
table on which it is defined.
database_name.
the name of the containing database for table_name if other than the
database specified for hash_index_name.
table_name
the name of the base table on which the hash index is defined.
You cannot define a hash index on any of the following database objects:
•
•
•
•
column_name_2
Global temporary table
Hash index
Join index
Journal table
• Queue table
• Trace table
• View (neither recursive nor
nonrecursive)
• Volatile table
An optional, explicitly specified column set on which the hash index rows
are distributed across the AMPs.
No column in a hash index can have a UDT, BLOB, or CLOB data type.
You cannot specify the system-derived columns PARTITION,
PARTITION#L1, PARTITION#L2, PARTITION#L3, PARTITION#L4,
PARTITION#L5, PARTITION#L6, PARTITION#L7, PARTITION#L8,
PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the
column_name_2 list.
You can, however, specify a user-defined column named PARTITION or
PARTITION#Ln, where n ranges from 1 - 15, inclusive.
The column set you specify must be drawn from the columns specified by
column_name_1.
318
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Syntax element …
Specifies …
column_name_2
(continued)
You cannot specify the same column twice in the column_name_2 list.
You cannot qualify any of the column names in the column_name_2 list.
You can, however, specify a user-defined column named partition.
You cannot compress column values for a hash index.
This column set acts as the primary index for the hash index: its rows are
hashed on the column set that you specify.
If you do not specify this column set, then the hash index rows are hashed
on the primary index column set of the base table on which the index is
defined, which makes it hash-local with respect to its base table.
You cannot specify a partitioned column set. This means that you cannot
create a PPI for hash indexes.
ORDER BY
the row ordering on each AMP: either value-ordered or hash-ordered.
If you do not specify an ORDER BY clause, then the hash index rows have
the same ordering as that specified for the base table on which the index is
defined.
You must specify an ORDER BY clause that includes an explicit column
list for a hash index defined on a partitioned primary index table.
Rules for using an ORDER BY clause are shown in the following two
tables:
SQL Reference: Data Definition Statements
IF you specify …
THEN …
a BY clause
you must specify an ORDER BY
clause for the hash index
definition.
neither a BY clause nor an
ORDER BY clause
the hash index rows are
distributed by the hash of the
primary index column set of the
base table on which they are
defined. As a result, the hash index
is AMP-local and the rows are
ordered by the hash of those
columns.
the system-derived PARTITION
column or the system-derived
PARTITION#Ln columns, where
n ranges between 1 and 15,
inclusive.
the request aborts and returns an
error to the requestor.
You can specify a user-defined
column named partition or
partition#Ln.
319
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Syntax element …
ORDER BY
(continued)
Specifies …
IF you specify
ORDER BY …
THEN …
VALUES with a
column_name_3
list
the column_name_3 list is limited to a single
numeric column with a size of 4 or fewer bytes.
In this case, the primary index of the base table
must consist of a single column having a length of 4
or fewer bytes.
The base table primary index column does not have
to be included in the column_name_1 set.
The hash index rows are stored in ascending order
by the values of the column specified as the
primary index of the base table.
The values specified for the column_name_3 list
must have one of the following data types:
•
•
•
•
•
VALUES
BYTEINT
DATE
DECIMAL
INTEGER
SMALLINT
HASH
• you must specify a BY clause
• the columns specified for the column_name_2
and column_name_3 sets must be identical.
The hash index rows are ordered on the row hash
value of these columns.
without
specifying the
HASH or
VALUES
keywords
the system orders the rows by VALUES by default.
In this case, you must specify a column_name_3
list.
value-ordering for the ORDER BY column.
Select VALUES to optimize queries that return a contiguous range of
values, especially for a workload that requires a covering index or that
commonly uses a nested join in its query plans.
HASH
320
hash-ordering for the ORDER BY column.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Syntax element …
Specifies …
column_name_3
the column set on which the index is to be ordered.
If you specify ORDER BY VALUES, then you can specify only one column
for column_name_3.
The specified column set must be a subset of column_name_1.
This means that you cannot specify the system-derived columns
PARTITION, PARTITION#L1, PARTITION#L2, PARTITION#L3,
PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11,
PARTITION#L12, PARTITION#L13, PARTITION#L14, or
PARTITION#L15 as part of the column_name_3 list.
You cannot specify the same column twice in the column_name_3 list.
You cannot compress column values for a hash index.
You cannot order an index by a LOB column.
ANSI Compliance
CREATE HASH INDEX is a Teradata extension to the ANSI SQL:2003 standard. ANSI does
not define DDL for creating indexes.
Authorization
You must have the CREATE TABLE privilege on the database in which the hash index is
created.
You must have the INDEX or DROP TABLE privilege on the indexed base table or its
containing database.
The creator of a hash index is granted the following table privileges on the index:
•
DROP TABLE
•
INDEX
•
DUMP
•
RESTORE
Privileges Granted Automatically
None.
Restriction on the Use of the PARTITION Keyword In a Hash Index
Definition
You cannot specify the system-derived column names PARTITION or PARTITION#Ln, where
n ranges between 1 and 15, inclusive, anywhere in the definition of a hash index.
You can specify a user-created column named partition.
SQL Reference: Data Definition Statements
321
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
UDTs And Hash Indexes
A UDT column cannot be a component of a hash index.
Specifying the Primary Index for a Hash Index
Like any other base table,19 including join indexes, a hash index must have a primary index.
Unlike other base tables, you do not use the keywords PRIMARY INDEX to specify the
primary index for a hash index.
The following table explains how the primary index for a hash index is defined:
IF you …
THEN the system creates the primary index for the hash index using
this column set …
do not define a BY clause
the primary index of the base table to which the hash index refers.
specify a BY clause and an
ORDER BY clause
the column set specified in the column_name_2 set in the BY
clause.
These columns must also be defined in the column_name_1 set.
Rows in a hash index defined with this type of primary index are
ordered either by row hash or by numeric value, depending on
what you specify in the ORDER BY clause.
Maximum Number of Hash, Join, and Secondary Indexes Definable Per
Data or Join Index Table
Up to 32 secondary,20 hash, and join indexes can be defined for one user data base table.
Permitting all secondary index operations for one table to be performed at the same time
allows the action to be treated as a single transaction; that is, either all of the indexes are
created, or none of them are created.
Comparison of Hash and Single-Table Join Indexes
The reasons for using hash indexes are similar to those for using single-table join indexes. Not
only can hash indexes optionally be specified to be distributed in such a way that their rows
are AMP-local with their associated base table rows, they can also provide an alternate direct
access path to those base table rows. This facility makes hash indexes somewhat similar to
secondary indexes in function. Hash indexes are also useful for covering queries so that the
base table need not be accessed at all.
The following list summarizes the similarities of hash and single-table join indexes:
•
Primary function of both is to improve query performance.
•
Both are maintained automatically by the system when the relevant columns of their base
table are updated by a delete, insert, or update operation.
19. The only exception is global temporary trace tables (see “CREATE GLOBAL TEMPORARY TRACE
TABLE” on page 303).
20. Each multicolumn NUSI defined with an ORDER BY clause counts as two consecutive indexes in this
calculation (see “Why Consecutive Indexes Are Important For Value-Ordered NUSIs” on page 340).
322
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
•
Both can be the object of any of the following SQL statements:
• COLLECT STATISTICS (Optimizer Form) • HELP INDEX
• DROP STATISTICS
• SHOW HASH INDEX
•
Both receive their space allocation from permanent space and are stored in distinct tables.
•
Both can be compressed, though the method of compression is different for each, and
both are different from the method of value compression used for base tables.
See “Compression of Hash Index Rows” on page 324, “Compression of Join Index Rows”
on page 382, and “Compressing Columns” on page 699, respectively, for the mechanisms
used to compress hash index rows, join index rows, and base table column values.
•
Both can be FALLBACK protected.
•
Neither can be queried or directly updated.
•
Neither can have a partitioned primary index.
•
Neither can store an arbitrary query result.
•
Neither can be used to partially cover a query that specifies the TOP n or TOP m
PERCENT option.
•
Both share the same restrictions for use with the MultiLoad, Teradata Parallel Transporter,
FastLoad, and Archive/Recovery utilities.
The following table summarizes the differences between hash and join indexes:
Hash Index
Join Index
Indexes one table only.
Can index multiple tables.
A logical row corresponds to one and only one
row in its referenced base table.
A logical row can correspond to multiple rows in
the referenced base tables.a
Column list cannot contain aggregate or ordered
analytical functions.
Column list can contain a restricted set of
aggregate functions.
Cannot have a secondary indexes.
Can have secondary indexes.
Supports transparently added, system-defined
columns that point to the underlying base table
rows.
Does not add underlying base table row pointers
implicitly.
Pointers to underlying base table rows can be
created explicitly by defining one element of the
column list using the keyword ROWIDb or by
including the index columns of the uniquec
primary index or USI on the base table.
a. This only happens with aggregation.
b. You can only specify ROWID in the outermost SELECT of the CREATE JOIN INDEX statement.
c. NUPIs cannot be used for this purpose.
Hash indexes provide a functional subset of the capabilities of join indexes. In other words,
any hash index has a functionally equivalent join index. The only difference between a hash
SQL Reference: Data Definition Statements
323
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
index and its functionally equivalent join index is that the hash index might be marginally
smaller than its equivalent join index.
To further emphasize this, each of the examples of creating a hash index at the end of the
CREATE HASH INDEX topic is accompanied by an example that creates an equivalent join
index. See “Example 1: UPI Base Table” on page 330 - “Example 13: Hash Index With LOW
Checksum Sampling” on page 335. Note that the functionally equivalent join indexes include
only the uniqueness part of the ROWID.
Compression of Hash Index Rows
The term compression is used to mean two entirely different things for the Teradata system.
Both forms are lossless, meaning that the original data can be reconstructed exactly from their
compressed forms:
•
When describing compression of hash and join indexes, compression refers to a logical
row compression in which multiple sets of nonrepeating column values are appended to a
single set of repeating column values. This allows the system to store the repeating value
set only once, while any nonrepeating column values are stored as logical segmental
extensions of the base repeating set.
•
When describing compression of column values, compression refers to the storage of those
values one time only in the table header, not in the row itself, and pointing to them by
means of an array of presence bits in the row header. The method is called Dictionary
Indexing, and it can be viewed as a variation of Run-Length Encoding (see Database
Design for additional information).
This topic refers to the first definition of compression in the preceding list.
When the following things are true, the system automatically compresses the rows of a hash
index:
•
The ordering column set is the same as the primary index column set of the base table.
•
The primary index of the base table is not unique.
Rows having the same values for the order key are compressed into a single physical row
having fixed and repeating parts. If the columns do not fit into a single physical row, they spill
over to additional physical rows as is necessary.
The fixed part of the row is made up of the explicitly-defined columns that define the
column_1 list. The repeating part is composed of the remaining columns, whether defined
implicitly or explicitly. See Database Design for a more detailed description of hash index row
compression.
324
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
The system only compresses row sets together if they are inserted by the same INSERT
statement. This means that rows that are subsequently inserted are not appended as logical
rows to existing compressed row sets, but rather are compressed into their own self-contained
row sets.
Note that while you can compress entire hash index rows, you cannot compress individual
column values for a hash index.
Collecting Statistics on a Hash Index
You should collect statistics on appropriate columns of a hash index frequently just as you
would for any base table or join index. For most applications, you should collect the statistics
on base table columns rather than on hash index columns. See “Why You Should Collect
Statistics on Base Table Columns Instead of Hash Index Columns” on page 326 for further
information.
When you create a hash index with a BY clause, you can collect and drop statistics on those
columns using an INDEX clause to specify the column set.
For example, suppose a hash index has the following definition:
CREATE HASH INDEX OrdHIdx8 (o_custkey, o_orderdate) ON Orders
BY (o_custkey, o_orderdate)
ORDER BY (o_orderdate);
Then you can collect statistics on the partitioning columns as shown in the following example:
COLLECT STATISTICS ON OrdHIdx8 INDEX (o_custkey, o_orderdate);
Note that you can only use columns specified in a BY clause definition if you use the keyword
INDEX in your COLLECT STATISTICS statement.
A poorer choice would be to collect statistics using the column clause syntax. To do this, you
must perform two separate requests.
COLLECT STATISTICS ON OrdHIdx8 COLUMN o_custkey;
COLLECT STATISTICS ON OrdHIdx8 COLUMN o_orderdate;
It is always better to collect the statistics for a multicolumn index on the index itself rather
than individually on its component columns because its selectivity is much better when you
collect statistics on the index columns as a set.
For example, a query with a condition like WHERE x=1 AND y=2 is better optimized if
statistics are collected on INDEX (x,y) than if they are collected individually on column x and
column y.
The same restrictions hold for the DROP STATISTICS statement.
The Teradata Statistics Wizard utility does not support hash indexes.
SQL Reference: Data Definition Statements
325
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Why You Should Collect Statistics on Base Table Columns Instead of Hash
Index Columns
The Optimizer substitutes base table statistics for hash index statistics when no demographics
have been collected for its hash indexes. Because of the way hash index columns are built, it is
generally best not to collect statistics directly on the index columns and instead to collect them
on the corresponding columns of the base table. This optimizes both system performance and
disk storage by eliminating the need to collect the same data redundantly.
You need to collect statistics on the hash index columns if you do not collect the statistics for
the relevant base table columns.
Guidelines for Collecting Statistics On Hash Index Columns
The guidelines for selecting hash index columns on which to collect statistics are similar to
those for base tables and join indexes. The primary factor to consider in all cases is whether
the statistics provide better access plans. If they do not, consider dropping them. If the
statistics you collect produce worse access plans, then you should always report the incident to
Teradata support personnel.
When you are considering collecting statistics for a hash index, it might help to think of the
index as a special kind of base table that stores a derived result. For example, any access plan
that uses a hash index must access it with a direct probe, a full table scan, or a range scan.
With this in mind, consider the following things when deciding which columns to collect
statistics for:
•
326
Consult the following table for execution plan issues related to collecting statistics on a
hash index:
IF an execution plan might involve …
THEN you should collect statistics on the …
search condition keys
column set that constitutes the search condition.
joining the hash index with another table
join columns to provide the Optimizer with the
information it needs to best estimate the
cardinalities of the join.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
•
•
Consult the following table for index definition issues related to collecting statistics on a
hash index:
IF the hash index is defined …
THEN you should collect statistics on the …
with a BY clause or ORDER BY clause (or
both)
primary index and ordering columns specified
by those clauses.
without a BY clause
primary index column set of the base table on
which the index is defined.
without an ORDER BY clause and the
ordering column set from the base table is
not included in the column_name_1 list
order columns of the base table on which the
index is defined.
This action provides the Optimizer with several
essential baseline statistics, including the
cardinality of the hash index.
If a hash index column appears frequently in WHERE clauses, you should consider
collecting statistics on it as well, particularly if that column is the sort key for a
value-ordered hash index.
Hash Indexes Are Maintained by the System
Hash indexes are automatically maintained by the system when update operations (UPDATE,
DELETE, INSERT) are performed on columns in their underlying base tables that are also
defined for the hash index. Additional steps are included in the execution plan to regenerate
the affected portion of the stored result.
Creating Hash Indexes for Tables With Partitioned Primary Indexes
You cannot create a partitioned primary index for a hash index, but you can create a hash
index on a table that has a partitioned primary index. To define a hash index on a PPI table,
you must also specify an ORDER BY clause that includes an explicit column list.
The column list cannot contain LOB or UDT columns.
If you experience 3710 errors when running queries against a PPI table with a hash index, you
can increase the amount of memory that is available to the Optimizer by updating several
DBSControl flags to values that ensure that it can process any request on the PPI table.
The recommended initial settings are as follows:
•
MaxParseTreeSegs = 2,000 for 32-bit systems
= 4,000 for 64-bit systems
•
OptMaxGlobalJI
=8
You might find that your query workloads are such that these values need to be increased still
further.
SQL Reference: Data Definition Statements
327
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
See Utilities for information about how to change the setting for the MaxParseTreeSegs field in
the DBS Control record. OptMaxGlobalJI is an internal DBSControl field. You must contact a
Teradata support representative to change its value.
Disk I/O Integrity Checking
The system permits you to select various levels of disk I/O integrity checking of your table data
using one of the following integrity checks ranked in order of their ability to detect errors:
1
Full end-to-end checksums (ALL)
Detects most bit, byte, and byte string errors.
2
Statistically sampled partial end-to-end checksums (LOW, MEDIUM, HIGH)
Detects lost writes and intermediate levels of bit, byte, and byte string errors.
3
Disable checksum disk I/O integrity checks. (NONE)
Detects some forms of lost writes using standard file system metadata verification.
The checksum setting applies to primary and fallback data rows for the hash index.
This feature detects and logs disk I/O errors: it does not fix them.
The more words used to generate the checksum value, the better able that checksum is to
detect disk I/O errors. Because CPU utilization increases as a function of the number of words
used to generate a checksum, several different levels of checking are provided so you can
adjust disk I/O integrity checking at the level of individual tables as needed, balancing
integrity checking against system performance.
You can specify system-wide checksum defaults for various table types using the Checksum
Levels fields of the DBSControl utility Disk I/O Integrity fields and you can specify the
system-wide checksum level definitions for the LOW, MEDIUM, and HIGH values using the
Checksum Level Definitions fields of the DBSControl utility Disk I/O Integrity fields. See
Utilities and Database Administration for details.
Restrictions and Limitations for Error Tables
You cannot create a hash index on an error table (see “CREATE ERROR TABLE” on
page 205).
Restrictions and Limitations for Load Utilities
You cannot use FastLoad, MultiLoad, or the Teradata Parallel Transporter operators LOAD and
UPDATE to load data into base tables that have hash indexes because those indexes are not
maintained during the execution of these utilities. If you attempt to load data into base tables
with hash indexes using these utilities, an error message returns and the load does not
continue.
To load data into a hash-indexed base table, you must drop all defined hash indexes before you
can run FastLoad, MultiLoad, or the Teradata Parallel Transporter operators LOAD and
UPDATE.
328
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Load utilities like TPump, BTEQ, and the Teradata Parallel Transporter operators INSERT
and STREAM, which perform standard SQL row inserts and updates, are supported for
hash-indexed tables.
Restrictions and Limitations for Archive and Restore
Though you can archive a database that contains hash indexes, the system does not
automatically rebuild those indexes when you restore the archived database; instead, they are
marked as not valid.
To work around this, you must drop and recreate the hash index and collect its statistics before
you can use it in a query.
When a hash index has been marked not valid, the SHOW HASH INDEX statement displays a
special status message to inform you that the hash index has been so marked.
Restrictions and Limitations for Ordered Analytical Functions
When an ordered analytical function is specified on columns that are also defined for a
compressed hash index, the Optimizer does not select the hash index to process the query.
Restrictions and Limitations for Large Objects
Hash indexes cannot contain BLOB or CLOB columns.
Restrictions and Limitations for UDTs
You cannot specify a column with a UDT type in the definition of a hash index, nor for any
other kind of index.
Restrictions and Limitations for Triggers
You cannot define triggers and hash indexes on the same table.
Restrictions and Limitations for the Reconfig Utility
You must drop and rebuild all value-ordered hash indexes after you run the Reconfig utility
(see Utilities).
The same is not true for hash-ordered hash indexes.
Restrictions on Creating a Hash Index on a Table Concurrent With Random
AMP Sample Emulation on That Table
You cannot create a hash index for a table while that table is subject to random AMP sample
emulation. If you attempt to do so, the system returns an error.
To disable random AMP sampling, use the DIAGNOSTIC HELP SAMPLES statement (see
“DIAGNOSTIC HELP SAMPLES” on page 1402) to determine which samples have been set,
then use the DIAGNOSTIC SET SAMPLES statement (see “DIAGNOSTIC SET SAMPLES”
on page 1404) to disable them.
SQL Reference: Data Definition Statements
329
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
If you want to use random AMP sampling on the table with a new hash index, you must use
the following general procedure:
1
Create the new hash index on the table on the target system.
2
Extract a fresh random AMP sample from the target system.
3
Apply the fresh sample to the source system.
4
End of procedure.
Permanent Journal Recovery of Hash Indexes Is Not Supported
You can use ROLLBACK or ROLLFORWARD statements to recover base tables that have hash
indexes defined on them; however, the hash indexes are not rebuilt during the recovery
process. Instead, they are marked as not valid. You must drop and recreate any such hash
indexes before the Optimizer can use them again to generate a query plan.
When a hash index has been marked not valid, the SHOW HASH INDEX statement displays a
special status message to inform you that the hash index has been so marked.
Examples for Base Table With Unique Primary Index
The subsequent examples demonstrate hash indexes based on the following table definition:
CREATE TABLE Orders (
o_orderkey
INTEGER
NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE
FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
UNIQUE PRIMARY INDEX (o_orderkey);
Example 1: UPI Base Table
The following hash index is distributed on its primary index o_orderdate and stored in value
order on o_orderdate:
CREATE HASH INDEX OrdHIdx_1 (o_orderdate) ON orders
BY (o_orderdate)
ORDER BY (o_orderdate);
Equivalently, you could specify ORDER BY VALUES instead of ORDER BY.
Note that the ORDER BY column list complies with the rules that it be limited to a single
column, that the column must be in the column_name_1 list, must be a numeric type, and
must be four or fewer bytes.
330
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
This creates an index that is equivalent in structure to the following single-table join index:
CREATE JOIN INDEX OrdJIdx1 AS
SELECT (o_orderdate), (o_orderkey, orders.ROWID)
FROM orders
ORDER BY o_orderdate
PRIMARY INDEX (o_orderdate);
Example 2: UPI Base Table
The following hash index is distributed on its primary index o_custkey and stored in row-hash
order on o_custkey:
CREATE HASH INDEX OrdHIdx_2 (o_custkey) ON orders
BY (o_custkey)
ORDER BY HASH (o_custkey);
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX OrdJIdx2 AS
SELECT (o_custkey), (o_orderkey, orders.ROWID)
FROM orders
PRIMARY INDEX (o_custkey);
Example 3: UPI Base Table
The following hash index is distributed on o_orderkey (the primary index for the base table
Orders) and stored in value order on o_orderkey (the order key for the base table orders):
CREATE HASH INDEX OrdHIdx_3 (o_orderdate) ON orders
ORDER BY VALUES;
Note that the ordering column of the base table complies with the rules that it be limited to a
single numeric column four or fewer bytes in length.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX OrdJIdx3 AS
SELECT o_orderkey, o_orderdate, orders.ROWID
FROM orders
ORDER BY o_orderkey
PRIMARY INDEX (o_orderkey);
Example 4: UPI Base Table
The following hash index is distributed on o_orderkey (the primary index for the base table
Orders) and stored in hash order on o_orderkey:
CREATE HASH INDEX OrdHIdx_4 (o_orderdate) ON orders;
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX OrdJIdx4 AS
SELECT o_orderkey, o_orderdate, orders.ROWID
FROM orders
PRIMARY INDEX (o_orderkey);
SQL Reference: Data Definition Statements
331
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Example 5: UPI Base Table
The following hash index is distributed on o_orderkey (the primary index for the base table
Orders) and stored in value order on o_orderdate:
CREATE HASH INDEX OrdHIdx_5 (o_orderdate) ON orders
ORDER BY (o_orderdate);
Equivalently, you could specify ORDER BY VALUES instead of ORDER BY.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX OrdJIdx5 AS
SELECT (o_orderdate), (o_orderkey, orders.ROWID)
FROM orders
ORDER BY o_orderdate
PRIMARY INDEX (o_orderkey);
Example 6: UPI Base Table
The following hash index is distributed on its primary index o_orderdate and stored in value
order on o_orderkey (the primary index for the base table orders):
CREATE HASH INDEX OrdHIdx_6 (o_orderdate) ON orders
BY (o_orderdate)
ORDER BY VALUES;
Note that the ordering column of the base table complies with the rules that it be limited to a
single numeric column four or fewer bytes in length.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX OrdJIdx6 AS
SELECT o_orderkey, o_orderdate, orders.ROWID
FROM orders
ORDER BY o_orderkey
PRIMARY INDEX (o_orderdate);
Examples for Base Table With Nonunique Primary Index
The subsequent examples demonstrate hash indexes based on the following table definition:
CREATE TABLE Lineitem (
l_orderkey
INTEGER
NOT NULL,
l_partkey
INTEGER
NOT NULL,
l_suppkey
INTEGER,
l_linenumber
INTEGER,
l_quantity
INTEGER
NOT NULL,
l_extendedprice DECIMAL(13,2) NOT NULL,
l_discount
DECIMAL(13,2),
l_tax
DECIMAL(13,2),
l_returnflag
CHARACTER(1),
l_linestatus
CHARACTER(1),
l_shipdate
DATE
FORMAT 'yyyy-mm-dd',
l_commitdate
DATE
FORMAT 'yyyy-mm-dd',
l_receiptdate
DATE
FORMAT 'yyyy-mm-dd',
l_shipinstruct VARCHAR(25),
l_shipmode
VARCHAR(10),
l_comment
VARCHAR(44))
PRIMARY INDEX (l_orderkey);
332
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Example 7: NUPI Base Table
The following hash index is distributed explicitly on l_shipdate and stored explicitly in value
order on l_shipdate:
CREATE HASH INDEX LineHIdx_1 (l_shipdate) ON lineitem
BY (l_shipdate)
ORDER BY (l_shipdate);
Equivalently, you could specify ORDER BY VALUES instead of ORDER BY.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx1 AS
SELECT (l_shipdate), (l_orderkey, lineitem.ROWID)
FROM lineitem
ORDER BY l_shipdate
PRIMARY INDEX (l_shipdate);
Example 8: NUPI Base Table
The following hash index is distributed explicitly on l_partkey and stored explicitly in
row-hash order on l_partkey:
CREATE HASH INDEX LineHIdx_2 (l_partkey) ON lineitem
BY (l_partkey)
ORDER BY HASH (l_partkey);
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx2 AS
SELECT (l_partkey), (l_orderkey, lineitem.ROWID)
FROM lineitem
PRIMARY INDEX (l_partkey);
Example 9: NUPI Base Table
The following hash index is distributed implicitly on l_orderkey, the primary index for the
base table lineitem, and stored explicitly in value order on l_orderkey:
CREATE HASH INDEX LineHIdx_3 (l_shipdate) ON lineitem
ORDER BY VALUES;
The ordering column of the base table complies with the rules that it be limited to a single
numeric column four or fewer bytes in length.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx3 AS
SELECT (l_orderkey), (l_shipdate, lineitem.ROWID)
FROM lineitem
ORDER BY l_orderkey
PRIMARY INDEX (l_orderkey);
SQL Reference: Data Definition Statements
333
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Example 10: NUPI Base Table
The following hash index is distributed implicitly on l_orderkey, the primary index for the
base table lineitem, and also stored implicitly in hash order on l_orderkey:
CREATE HASH INDEX LineHIdx_4 (l_shipdate) ON lineitem;
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx4 AS
SELECT (l_orderkey), (l_shipdate, lineitem.ROWID)
FROM lineitem
PRIMARY INDEX (l_orderkey);
Example 11: NUPI Base Table
The following hash index is distributed implicitly on l_orderkey, the primary index for the
base table lineitem, and stored explicitly in value order on l_shipdate:
CREATE HASH INDEX LineHIdx_5 (l_shipdate) ON lineitem
ORDER BY (l_shipdate);
Equivalently, you could specify ORDER BY VALUES instead of ORDER BY.
Note that the ORDER BY column list complies with the rules that it be limited to a single
column, that the column must be in the column_name_1 list, must be a numeric type, and
must be four or fewer bytes.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx5 AS
SELECT (l_shipdate), (l_orderkey, lineitem.ROWID)
FROM lineitem
ORDER BY l_shipdate
PRIMARY INDEX (l_orderkey);
Example 12: NUPI Base Table
The following hash index is distributed explicitly on l_shipdate and stored implicitly in value
order on l_orderkey, the primary index for the base table lineitem:
CREATE HASH INDEX LineHIdx_6 (l_shipdate) ON lineitem
BY (l_shipdate)
ORDER BY VALUES;
Note that the ordering column of the base table complies with the rules that it be limited to a
single numeric column four or fewer bytes in length.
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx6 AS
SELECT (l_orderkey), (l_shipdate, lineitem.ROWID)
FROM lineitem
ORDER BY l_orderkey
PRIMARY INDEX (l_shipdate);
334
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE HASH INDEX
Example 13: Hash Index With LOW Checksum Sampling
The following hash index is created with a disk I/O checksum level of LOW:
CREATE HASH INDEX LineHIdx_6, CHECKSUM = LOW
(l.shipdate) ON lineitem
BY (l_shipdate)
ORDER BY VALUES;
This creates an index that is equivalent in structure to the following join index:
CREATE JOIN INDEX LineJIdx6, CHECKSUM = LOW AS
SELECT (l_orderkey), (l_shipdate, lineitem.ROWID)
FROM lineitem
ORDER BY l_orderkey
PRIMARY INDEX (l_shipdate);
Related Topics
For an overview of Teradata Database hash indexes, see SQL Reference: Fundamentals.
For more examples and discussion of the functions and features of hash indexes, and for an
overview of disk I/O integrity checking, see Database Design.
Also see “CREATE JOIN INDEX” on page 346.
SQL Reference: Data Definition Statements
335
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
CREATE INDEX
Purpose
Creates a set of new secondary indexes on an existing data table or join index.
Syntax
,
CREATE
INDEX
,
A
(
A
index_name
UNIQUE
ALL
64
index_column_name
B
)
ORDER BY
VALUES
(
order_column_name
)
HASH
B
table_name
ON
TEMPORARY
database_name.
;
join_index_name
database_name.
1101G004
where:
Syntax Element …
Specifies …
UNIQUE
that no two rows in the table can have the same value or combination of values in the indexed fields.
You cannot specify UNIQUE if you also specify ALL.
You cannot specify UNIQUE for a secondary index on a join index.
You cannot specify UNIQUE if you also specify an ORDER BY clause.
index_name
336
an optional name for the secondary INDEX. The maximum number of characters an index name
can contain is 30. See SQL Reference: Fundamentals for a description of Teradata Database identifiers
and a list of the characters they can contain.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
Syntax Element …
Specifies …
ALL
that a NUSI should maintain row ID pointers for each logical row of a join index, not just the
compressed physical rows.
You cannot specify the ALL option for primary or unique secondary indexes: it is used for secondary
indexes created on join indexes only.
The ALL option ignores the assigned case specificity for a column. This property enables a NUSI
defined with the ALL option to do the following:
• Include case-specific values.
• Cover a table or join index on a NOT CASESPECIFIC column set.
ALL enables a NUSI to cover a join index, enhancing performance by eliminating the need to access
the join index itself when all columns needed by a query are contained in the NUSI.
Be aware that specifying the ALL option might also require additional index storage space.
Use this keyword when a NUSI is being defined for a join index and you want to make it eligible for
the Optimizer to select when covering reduces access plan cost.
You cannot specify multiple NUSIs that differ only by the presence or absence of the ALL option.
index_column_name
the names of one or more columns whose values are to be indexed.
No column in a secondary index can have a UDT or LOB data type.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the index_column_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where n
ranges from 1 - 15, inclusive.
You cannot compress column values for a secondary index.
You can specify up to 64 columns for the new index. The index is based on the combined values of
each column. Unless you specify the ORDER BY clause, the index is hash-ordered on all its columns.
If you specify more than one column name, the index is created on the combined values of each
column named. A maximum of 32 secondary indexes can be created for one table.a
Multiple indexes can be defined on the same columns as long as each index differs in its ordering
option (VALUES versus HASH).
ORDER BY
row ordering on each AMP by a single NUSI column: either value-ordered or hash-ordered.
If you specify HASH, then the rows are hash-ordered on the AMP; otherwise, the rows are
value-ordered.
Each multicolumn NUSI created with an ORDER BY clause counts as two consecutive indexes
against the maximum of any mix of 32 secondary, hash, and join indexes that can be defined per
table.a
If you do not specify an ORDER BY clause, the system automatically hash orders index rows on their
columns.
You cannot order by the system-derived PARTITION or PARTITION#Ln columns. You can,
however, specify a user-defined column named partition.
VALUES
value-ordering for the ORDER BY column.
Select VALUES to optimize queries that return a contiguous range of values, especially for a covered
index or a nested join.
SQL Reference: Data Definition Statements
337
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
Syntax Element …
Specifies …
HASH
hash-ordering for the ORDER BY column.
Select HASH to limit hash-ordering to one, rather than all, columns.
Hash-ordering a multicolumn NUSI on one of its columns allows the NUSI to participate in a
nested join where join conditions involve only that ordering column.
order_column_name
a column in the index_column_name list that specifies the sort order to be used.
No column in a secondary index can have a UDT or LOB data type.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the order_column_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where n
ranges from 1 - 15, inclusive.
Supported data types for a value-ordered, four-bytes-or-less order_column_name are:
• BYTEINT
• DATE
• DECIMAL
• INTEGER
• SMALLINT
If you specify ORDER BY without also specifying an explicit order_column_name, then the system
uses the first column specified in the index_column_name list to order the rows in the index.
TEMPORARY
that the table is a global temporary table and the index is being created on its instance in the current
session.
If you do not specify TEMPORARY then the index is created on the base global temporary table
definition. In this case, if there are materialized instances of the table you cannot create the index on
the base global temporary table.
If you specify TEMPORARY against a permanent table, the system returns an error.
You cannot create indexes on a volatile table.
database_name
the name of the containing database for table_name if other than the current database.
table_name
the table for which an index is to be created.
You cannot specify the name of any of the following:
• Derived table
• Hash index
• Journal table
• View (both forms)
• Volatile table
database_name
the name of the containing database for join_index_name if other than the current database.
join_index_name
the name of the join index on which this index is to be defined.
You cannot define a USI on a join index. NUPIs are allowed.
a. Each multicolumn NUSI defined with an ORDER BY clause counts as two consecutive indexes in this calculation (see “Why
Consecutive Indexes Are Important For Value-Ordered NUSIs” on page 340).
338
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
ANSI Compliance
CREATE INDEX is a Teradata extension to the ANSI SQL:2003 standard. ANSI does not
define DDL for creating indexes.
The CREATE UNIQUE INDEX syntax is functionally equivalent to adding a UNIQUE NOT
NULL or PRIMARY KEY NOT NULL constraint set to a column in ANSI SQL:2003.
Authorization
You must have the INDEX or DROP TABLE privilege on the named table or join index.
Privileges Granted Automatically
None.
Restriction on the Use of the PARTITION and PARTITION#Ln Keywords In
a Secondary Index Definition
You cannot specify the system-derived columns PARTITION or PARTITION#Ln, where n
ranges from 1 to 15, inclusive, anywhere in the definition of a secondary index.
You can specify a user-created column named partition.
Locks and Concurrency
The severity of locking you specify with a LOCKING modifier does not always match the
severity of locking applied by the Lock Manager, as the following table describes:
IF you explicitly specify this lock severity for the
table that contains the index columns …
THEN the system places this lock severity on that
table …
• None
• WRITE
WRITE
• ACCESS
• READ
• SHARE
READ
EXCLUSIVE
EXCLUSIVE
For more information about locking severities, see SQL Reference: Statement and Transaction
Processing.
For more information about the LOCKING modifier, see SQL Reference: Data Manipulation
Statements).
The READ or WRITE lock is upgraded to an EXCLUSIVE severity after the index subtables
are created, but prior to locking the dictionary and modifying the headers. This improves
concurrency by reducing the time SELECT statements against the table are blocked.
SQL Reference: Data Definition Statements
339
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
If you do not specify an explicit EXCLUSIVE lock, then a CREATE INDEX statement on a
table can run concurrently with a SELECT statement that has an ACCESS or READ lock on
the same table until the lock is upgraded to a severity of EXCLUSIVE. When that occurs, the
statement that requests the lock first blocks the other.
A CREATE INDEX statement holding an EXCLUSIVE lock on a table can run concurrently
with a COLLECT STATISTICS statement on that table until the CREATE INDEX statement
requests that the lock be upgraded to EXCLUSIVE. When that occurs, the CREATE INDEX
statement is blocked until the COLLECT STATISTICS statement completes. Any subsequent
COLLECT STATISTICS statements on the table are blocked until the CREATE INDEX process
completes.
A CREATE INDEX statement cannot run concurrently against the same table with an ALTER
TABLE statement or another CREATE INDEX statement. The statement that first requests the
lock blocks the other.
Maximum Number of Indexes Definable Per CREATE INDEX Statement and
Per Data, Hash, or Join Index Table
Up to 32 secondary indexes can be defined for one CREATE INDEX statement. Also, up to 32
secondary21, hash, and join indexes can be defined for one table. Permitting all secondary
index operations for one table to be performed at the same time allows the action to be treated
as a single transaction; that is, all of the indexes are created, or none of them are created. You
can define up to 64 columns for each secondary index you create.
You can also create secondary indexes on user data base tables and join indexes as part of the
CREATE TABLE and CREATE JOIN INDEX statements, respectively. See “CREATE TABLE
(Index Definition Clause)” on page 716 and “CREATE JOIN INDEX” on page 346 for details.
Why Consecutive Indexes Are Important For Value-Ordered NUSIs
The system automatically assigns incrementally increasing numbers to indexes when they are
created on a table. This is not important externally except for the case of value-ordered
multicolumn NUSIs created with an ORDER BY clause, because they not only consume two
of the allotted 32 index numbers from the pool, but those two index numbers are
consecutive.22
To understand why this is important, consider the following scenario:
1
You create 32 indexes on a table, none of which is value-ordered.
2
You drop every other index on the table.23
For example, if you had dropped all the even-numbered indexes, there would now be 16
odd-numbered index numbers available to be assigned to indexes created in the future.
21. Each multicolumn NUSI created with an ORDER BY clause counts as two consecutive indexes in this
calculation (see “Why Consecutive Indexes Are Important For Value-Ordered NUSIs” on page 340).
22. One index of the consecutively numbered pair represents the column list, while the other index in the pair
represents the ordering column.
23. Meaning that you drop either all the odd-numbered indexes or all the even-numbered indexes.
340
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
3
You attempt to create a multicolumn NUSI with an ORDER BY clause.
The request aborts and the system returns an error message to you.
The reason the request aborts is that two consecutive index numbers were not available for
assignment to the ordered multicolumn NUSI.
You are still able to create 16 additional value-ordered single column NUSIs,
non-value-ordered NUSIs, USIs, hash indexes, or join indexes, but you cannot create any
ordered multicolumn NUSIs.
To work around this problem, perform the following procedure:
1
Drop any index on the table.
This action frees 2 consecutive index numbers.
2
Create the ordered multicolumn NUSI that failed previously.
3
Recreate the index you dropped to free the consecutive index numbers.
4
End of procedure.
Storage and Performance Considerations for Secondary Indexes
Secondary indexes are stored in subtables separately from their associated data and join index
tables. This means that each secondary index subtable that is created requires additional disk
space.
Additionally, insert, delete, and update operations require more processing time for tables
with secondary indexes because the index subtables must be updated each time an indexed
field in an associated row in their parent data or join index table is updated.
Secondary Indexes Can Shorten Search Time
Secondary index values can shorten table search time for multirow selection. Multirow
selection is often referred to as set selection. Each row in a secondary index subtable is made
up of the index value and one or more row IDs that point to the data row set containing that
value. Therefore, when secondary index values are used as conditional expressions in SQL
statements, only the row set that contains the specified value is accessed.
CREATE INDEX and the QITS Column of Queue Tables
You cannot create a USI on the QITS column of a queue table (see “CREATE TABLE (Queue
Table Form)” on page 817).
SQL Reference: Data Definition Statements
341
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
UNIQUE Versus Nonunique
The UNIQUE option creates a USI which, perhaps redundantly, prevents the occurrence of
duplicate index values in the indexed base table. Only one row can have a value set in the
column set that corresponds to an entry in the subtable of a unique secondary index. The
subtable of a unique secondary index is a hashed table, which is very efficient for retrieving a
single row.
When the values of nonunique secondary indexes are used to apply complex conditional
expressions to very large tables, efficient retrieval is achieved by bit mapping the subtable row
IDs.
Use EXPLAIN or Visual Explain to Analyze the Usefulness of Secondary
Indexes
Before a request is processed, the Optimizer estimates comparative costs to determine whether
the use of a secondary index offers savings or is plausible. If not, it uses a different access
method. It is advisable, therefore, to test the performance of a secondary index before
implementing it.
You can use either the SQL EXPLAIN request modifier (see SQL Reference: Data Manipulation
Statements) or the Visual Explain client utility (see Teradata Visual Explain User Guide) to
generate a description of the processing sequence to help determine whether a secondary
index should be retained. You can also use the Teradata Index Wizard client utility to
determine optimum secondary indexes for particular SQL workloads. See Teradata Index
Wizard User Guide and SQL Reference: Statement and Transaction Processing.
Named Indexes
The index name must conform to the usual rules for a Teradata Database SQL identifier and
be unique in the table.
Also see “DROP INDEX” on page 1020.
Relationships Between Secondary Indexes and Primary Indexes
You can create a USI on the same column set that defines a nonunique primary index for a
table. When this redundant USI has been created, you can then use ALTER TABLE to change
the primary index on the table from a NUPI to a UPI. You cannot make this conversion for
PPIs unless all partitioning columns are also defined in the primary index column list.
You can create a value-ordered NUSI on the same column set that defines the primary index.
This is valid for a PPI even if the primary index column set does not include all the columns
used in the partitioning expression.
You can create a non-value-ordered NUSI on the same column set that defines the primary
index for a PPI table when the primary index column set does not include all the columns
specified for the partitioning expression.
Defining a USI or NUSI on the same column set as the primary index for a PPI table can
provide better performance for primary index accesses to that table.
342
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
Disk I/O Integrity Checking
The system assigns secondary indexes the same level of disk I/O integrity checking defined for
their associated user data or join index base tables, so you need not, and cannot, create any
disk I/O integrity checks for them.
Restrictions and Limitations for Error Tables
You can use the CREATE INDEX statement to add a secondary index to an error table (see
“CREATE ERROR TABLE” on page 205) to facilitate scanning its captured data for analysis.
If you do this, you must then drop any of the secondary indexes you have defined before you
perform an INSERT … SELECT or MERGE operation that specifies error logging on the data
table associated with the error table.
Restrictions and Limitations for Large Objects
Secondary indexes cannot contain BLOB or CLOB columns.
Restrictions and Limitations for UDTs
You cannot reference a column with a UDT type in the definition of a secondary index, nor
for any other kind of index.
Restrictions on Creating a Secondary Index on a Table Concurrent With
Random AMP Sample Emulation on That Table
You cannot create a secondary index for a table while that table is subject to random AMP
sample emulation. If you attempt to do so, the request aborts and the system returns an error
to the requestor.
To disable random AMP sampling, use the DIAGNOSTIC HELP SAMPLES statement (see
“DIAGNOSTIC HELP SAMPLES” on page 1402) to determine which samples have been set,
then use the DIAGNOSTIC SET SAMPLES statement (see “DIAGNOSTIC SET SAMPLES”
on page 1404) to disable them.
If you want to use random AMP sampling on the table with a new secondary index, you must
use the following general procedure:
1
Create the new secondary index on the table on the target system.
2
Extract a fresh random AMP sample from the target system.
3
Apply the fresh sample to the source system.
4
End of procedure.
SQL Reference: Data Definition Statements
343
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
Example 1: Named Indexes
This example demonstrates a named secondary index.
CREATE UNIQUE INDEX Ident (Name, SocSecNo) ON Employee;
This definition allows the named index to be dropped by using its name:
DROP INDEX Ident ON Employee;
Example 2: Creating a Named Unique Secondary Index
This example creates a named unique secondary index index_1. Index index_1 must not be an
existing name in table table_1.
CREATE UNIQUE INDEX index_1 (field_1, field_2) ON table_1;
Example 3: Creating a Named Nonunique Secondary Index
This example creates a named nonunique secondary index index_2. Index index_2 must not
be an existing name in table table_2.
CREATE INDEX index_2 (field_1) ON table_2;
Example 4: Creating an Unnamed Unique Secondary Index
This example creates an unnamed unique secondary index.
CREATE UNIQUE INDEX (field_1, field_2) ON table_3;
Example 5: Creating an Unnamed Nonunique Secondary Index
The first example creates a nonunique secondary index on the dept_no column of the
employee table:
CREATE INDEX (dept_no) ON employee;
The UNIQUE option is not used in this statement because multiple rows contain the same
department number. The index should be useful, however, because department numbers are
often used for conditional retrievals and for ordering employee listings.
The second example creates an unnamed nonunique secondary index on the field_1 column
of a table named table_4.
CREATE INDEX (field_1) ON table_4;
344
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE INDEX
Example 6: Creating a Secondary Index On a Join Index
This example creates a secondary index on a join index defined in the example set for CREATE
JOIN INDEX (see “CREATE JOIN INDEX” on page 346) and then shows the explanation for
a query made against the base tables that uses both indexes.
Note that you cannot create a unique secondary index on a join index; any secondary index
must be nonunique.
CREATE INDEX shipidx (l_shipdate) ON OrderJoinLine;
*** Index has been created.
*** Total elapsed time was 5 seconds.
EXPLAIN SELECT o_orderdate, o_custkey, l_partkey, l_quantity,
l_extendedprice
FROM lineitem, order
WHERE l_orderkey = o_orderkey
AND
l_shipdate = '1997-09-18';
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
RowHash to prevent global deadlock for LOUISB.OrderJoinLine.
2) Next, we lock LOUISB.OrderJoinLine for read.
3) We do an all-AMPs RETRIEVE step from join index table
LOUISB.OrderJoinLine by way of index # 12
"LOUISB.OrderJoinLine.l_shipdate = 970918" with a residual
condition of ("(NOT (LOUISB.OrderJoinLine.o_orderdate IS NULL ))
AND (LOUISB.OrderJoinLine.l_shipdate = 970918)") into Spool 1,
which is built locally on the AMPs. The input table will not be
cached in memory, but it is eligible for synchronized scanning.
The result spool file will not be cached in memory. The size of
Spool 1 is estimated to be 500 rows. The estimated time for this
step is 0.37 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
Related Topics
For an overview of Teradata Database secondary indexes, see the following manuals:
•
SQL Reference: Fundamentals
• Database Design
SQL Reference: Fundamentals provides a brief overview of secondary indexes, while Database
Design provides a detailed overview.
SQL Reference: Data Definition Statements
345
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
CREATE JOIN INDEX
Purpose
Creates a join index that has one of the following functions:
•
Joins multiple tables, optionally with aggregation, in a prejoin table.
•
Replicates all or a vertical subset of a single base table and distributes its rows by a primary
index on a foreign key column to facilitate joins of very large tables by hashing them to the
same AMP.
•
Aggregates one or more columns of a single table or the join results of multiple tables in a
summary table.
•
Functions as a sparse join index subtable that contains only those rows that satisfy the
conditions specified by its WHERE clause.
Syntax
join_index_name
CREATE JOIN INDEX
AS
database_name.
SELECT
A
,
,
FALLBACK
PROTECTION
NO
CHECKSUM = integrity_checking_level
,
column_1_name
ROWID
A
table_name.
B
column_name_alias
AS
database_name.
EXTRACT
(
YEAR
date_expression
FROM
expression_alias
)
AS
MONTH
,
64
column_1_name
ROWID
(
table_name.
)
AS
a
column_name_alias
database_name.
,
,
a
64
column_2_name
ROWID
(
table_name.
)
AS
column_name_alias
database_name.
,
column_name
ROWID
table_name.
AS
database_name.
( numeric_expression
SUM
COUNT
( column_expression
EXTRACT (
YEAR
FROM
column_name_alias
expression_alias
)
)
date_expression
AS
)
MONTH
,
B
table_name
FROM
C
database_name.
correlation_name
WHERE
search_condition
AS
joined_table
D
C
,
GROUP BY
column_name
column_position
D
,
ORDER BY
column_name
column_position
indexes
;
1101H294
346
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Joined_Table Excerpt
joined_table
(joined_table)
joined_table
JOIN
joined_table
search_condition
ON
INNER
LEFT
RIGHT
OUTER
table_name
correlation_name
AS
1101E050
Indexes Excerpt
indexes
,
,
(
PRIMARY INDEX
64
primary_index_column
)
index_name
partitioning_expression
PARTITION BY
,
(
,
UNIQUE
INDEX
(
15
partitioning_expression
(
64
index_column_name
)
index_name
,
INDEX
(
index_name
ALL
64
index_column_name
)
ORDER BY
(
order_column_name
)
VALUES
HASH
1101I051
where:
Syntax Element …
Specifies …
Table Options Clause
This clause provides basic information about the join index being created: its containing database, its name, whether or not
it is fallback-protected, and whether or not disk I/O integrity checking is enabled.
database_name
an optional database name specified if the join index is to be contained in a database other than
the current database.
SQL Reference: Data Definition Statements
347
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
join_index_name
the name given to the join index created by this statement.
Join index names conform to the rules for naming tables, including explicit qualification with a
database or user name.
A join index need not be defined in the same database as the base tables represented in its
definition.
FALLBACK
[PROTECTION]
that the join index uses fallback protection.
NO FALLBACK
[PROTECTION]
that the join index does not use fallback protection. This is the default.
PROTECTION is an optional noise keyword that has no effect on the join index definition.
PROTECTION is an optional noise keyword that has no effect on the join index definition.
Note that if a join index is not fallback protected, an AMP failure prevents the following events
from occurring:
• Processing queries on the join index.
• Updating the base table on which the join index is defined.
CHECKSUM =
integrity_checking_level
a table-specific disk I/O integrity checksum level.
The checksum setting applies to primary data rows, fallback data rows, and all secondary index
rows for the join index.
If you do not specify a value, then the system assumes the system-wide default value for this table
type. The result is identical to specifying DEFAULT.
If you are changing the checksum for this table to the system-wide default value, then specify
DEFAULT.
You can change the percentage of sampling for the system-wide default values for LOW,
MEDIUM, and HIGH using the Checksum Level Definitions fields in the DBSControl utility (see
Utilities). The values provided here for those checksum percentages are the defaults specified by
the installation or upgrade.
You cannot change the sampling percentage for the following:
• The system-wide default values ALL and NONE.
• Dictionary tables.
Level
Checksum Sample Count Percentage
ALL
100
DEFAULT
Percentage specified for this table type in the Checksum Levels fields of the
Disk I/O Integrity Fields in the DBSControl utility (see Utilities).
HIGH
67
MEDIUM
33
LOW
NONE
2
Disable checksum disk I/O integrity checks.
End Table Options Clause
348
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
SELECT Clause
This clause projects the columns from one or more base tables that are to be included in the join index definition.
The options you can specify for this clause are identical to those for any other SELECT statement except where explicitly
contradicted.
Among the prohibited options that are available for ordinary SELECT statements are the following clauses: TOP n, FULL
OUTER JOIN, CROSS JOIN, HAVING, QUALIFY, and SAMPLE; all functions except CAST, COUNT, EXTRACT, and
SUM; the set operators UNION, EXCEPT/MINUS, INTERSECT, and their derivatives; and subqueries.
Note that some of the optional clauses the system accepts do not become part of the join index definition. Examples include
such things as output FORMAT and TITLE phrases. You can determine if any of the options you specify do not become part
of the stored join index definition by performing a SHOW JOIN INDEX statement to view the DDL for the CREATE JOIN
INDEX statement of interest.
database_name.
table_name
the fully qualified path to column_1_name, if they are required for unique identification of
column_1_name or ROWID.
column_1_name
the name of a column to be included in the join index.
ROWID
No column in a join index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a join index.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_1_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
If two specified columns have the same name, both names must be aliased using a column name
alias. See SQL Reference: Fundamentals.
Specify the keyword ROWID as one of the values for either the column_1_name list or the
column_2_name list to enable the Optimizer to join a partial covering index to its base table to
access any noncovered columns.
You can alias both column_1_name and ROWID with a column name alias.
If you reference multiple tables in the join index definition, then you must fully qualify each
ROWID specification.
If you reference a ROWID in a GROUP BY clause, then you must define a column name alias for
it. The literal ROWID is not valid in the column list argument of a GROUP BY specification.
If you reference a ROWID column name alias in the select list of a join index definition, then you
can also reference that column name alias in a CREATE INDEX statement that creates a
secondary index on the join index; however, you cannot directly reference the ROWID keyword in
a CREATE INDEX statement.
You can only specify ROWID in the outermost SELECT list of the CREATE JOIN INDEX
statement.
Even though you do not explicitly specify this join when you write your query, it counts against
the 64 table restriction on joins.
SQL Reference: Data Definition Statements
349
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
column_1_name
If you also define a column_2_name list (see “column_2_name” on page 352), then the system
stores each distinct value of the column_1_name list only once.
ROWID (continued)
You can specify no more than 64 columns per referenced base table per join index.
IF column_2_name is …
THEN the limit on the total number of columns that can be
specified for the column_1 _name list is …
defined
64.
not defined
not defined.
The maximum is restricted only by the number of
columns that can be defined within the row size limit.
This limit is not related in any way to the restriction of
64 columns that can be defined per referenced base table
per join index.
[AS]
column_name_alias
an alias for column_1_name or ROWID. Do not use the name CountStar if you create an
aggregate join index because the system reserves that name for any expression being summed,
counted, or extracted in the aggregate definition.
EXTRACT YEAR |
MONTH FROM
to use the EXTRACT date function to extract a year or month from a date column.
See SQL Reference: Functions and Operators for more information about the EXTRACT function.
Note that join index definitions support only the extraction of years and months from a date
column.
date_expression
a date column or date expression from which either the year or the month is to be extracted.
[AS] expression_alias
a mandatory unique alias for a sum, count, or extracted year or month. This name permits
further use of the result as the grouping key for a GROUP BY clause or the ordering key for an
ORDER BY clause.
database_name.
table_name
the fully qualified path to column_1_name for a compressed join index definition, if required for
unique identification of column_1_name or ROWID.
column_1_name |
the name of a column to be included in the fixed portion of a compressed join index.
ROWID
No column in a join index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a join index.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_1_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
If two specified columns have the same name, both names must be aliased using a column name
alias. See SQL Reference: Fundamentals.
350
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
column_1_name |
Specify the keyword ROWID as one of the values for the column_1_name list to enable the
Optimizer to join a partial covering index to its base table to access any noncovered columns.
ROWID (continued)
You can alias both column_1_name and ROWID with a column name alias.
If you reference multiple tables in the join index definition, then you must fully qualify each
ROWID specification.
If you reference a ROWID in a GROUP BY clause, then you must define a column name alias for
it. The literal ROWID is not valid in the column list argument of a GROUP BY specification.
If you reference a ROWID column name alias in the select list of a join index definition, then you
can also reference that column name alias in a CREATE INDEX statement that creates a
secondary index on the join index.
However, you cannot directly reference the ROWID keyword in a CREATE INDEX statement.
You can only specify ROWID in the outermost SELECT list of the CREATE JOIN INDEX
statement.
Even though you do not explicitly specify this join when you write your query, it counts against
the 64 table restriction on joins.
You can specify no more than 64 columns per referenced base table per join index.
[AS]
column_name_alias
an alias for column_1_name or ROWID.
database_name.
table_name
the fully qualified path to column_2_name for a compressed join index definition, if required for
unique identification of column_2_name or ROWID.
column_2_name |
one of a list of multiple columns to be included in the join index. This column set represents the
repeated portion of the join index row. These columns form the compressed portion of a
compressed join index definition.
ROWID
You cannot define a partitioned primary index for a join index that is also compressed.
No column in a join index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a join index.
If two specified columns have the same name, both names must be aliased using a column name
alias. See SQL Reference: Fundamentals.
You can specify the keyword ROWID as one of the values for column_2_name to enable the
Optimizer to join a partial covering index to its base table to access any noncovered columns. Do
not duplicate the ROWID specification if you have already defined ROWID as one of the
column_1_name list values.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_2_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
You can alias both column_2_name and ROWID with a column name alias.
If you reference a ROWID in a GROUP BY clause, then you must define a column name alias for
it. The literal ROWID is not valid in the column list argument of a GROUP BY specification.
If you reference multiple tables in the join index definition, then you must fully qualify each
ROWID specification.
SQL Reference: Data Definition Statements
351
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
column_2_name
If you reference a ROWID column name alias in the select list of a join index definition, then you
can also reference that column name alias in a CREATE INDEX statement that creates a
secondary index on the join index.
ROWID (continued)
You can only specify ROWID in the outermost SELECT list of the CREATE JOIN INDEX
statement.
Even though you do not explicitly specify this join when you write your query, it counts against
the 64 table restriction on joins.
Do not specify column_2_name values for aggregate join indexes.
You can specify no more than 64 columns for column_2_name.
If you specify column_2_name, then you can specify no more than 64 columns for
column_1_name because the total column limit for a compressed join index is 128 columns.
There is no limit for the number of these repeated portions that can be stored for a given fixed
portion of a join index; however, there is a physical limit in that the total size of any one fixed
portion/repeated portion pair cannot exceed the Teradata Database row size limit.
[AS]
column_name_alias
an alias for column_2_name or ROWID. Do not use the name CountStar if you create an
aggregate join index because the system reserves that name for any expression being summed or
counted in the index definition.
Aggregation Clause
database_name.
table_name.
the fully qualified path to column_1_name, if required for unique identification of
column_1_name or ROWID.
column_1_name |
the name of a column to be included in the non-aggregate portion of an aggregate join index.
ROWID
No column in a join index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a join index.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_1_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
If two specified columns have the same name, both names must be aliased using a column name
alias. See SQL Reference: Fundamentals.
Specify the keyword ROWID as one of the values for the column_1_name list to enable the
Optimizer to join a partial covering index to its base table to access any noncovered columns.
You can alias both column_1_name and ROWID with a column name alias.
If you reference multiple tables in the join index definition, then you must fully qualify each
ROWID specification.
If you reference a ROWID in a GROUP BY clause, then you must define a column name alias for
it. The literal ROWID is not valid in the column list argument of a GROUP BY specification.
If you reference a ROWID column name alias in the select list of a join index definition, then you
can also reference that column name alias in a CREATE INDEX statement that creates a
secondary index on the join index.
352
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
column_1_name |
However, you cannot directly reference the ROWID keyword in a CREATE INDEX statement.
ROWID (continued)
You can only specify ROWID in the outermost SELECT list of the CREATE JOIN INDEX
statement.
Even though you do not explicitly specify this join when you write your query, it counts against
the 64 table restriction on joins.
You can specify no more than 64 columns per referenced base table per join index.
[AS]
column_name_alias
an alias for column_1_name or ROWID. Do not use the name CountStar if you create an
aggregate join index because the system reserves that name for any expression being summed,
counted, or extracted in the aggregate definition.
SUM
to use the SUM aggregate function to compute the sum of the column or column expression
specified by numeric_expression.
Note that SUM DISTINCT is not permitted.
If you specify SUM only, then the system adds a COUNT(*) expression to the column list and
names it CountStar.
See SQL Reference: Functions and Operators for more information about the SUM operator.
numeric_expression
an expression having a numeric data type that is to be summed over a specified column.
To avoid overflow, type the SUM numeric_expression specification in a join index definition as
FLOAT. If you do not assign a data type, the system types it as FLOAT automatically. If you assign
a type other than FLOAT, the system returns an error message to the requestor.
COUNT
to use the COUNT aggregate function to count the number of values in the column or column
expression specified by column_expression.
Note that COUNT DISTINCT is not permitted.
See SQL Reference: Functions and Operators for more information about the COUNT operator.
Note that all aggregate join indexes must have either a COUNT(*) or a
COUNT(non_null_expression) in their definition to support index maintenance.
If none is specified, the system creates a COUNT(*) implicitly, adds it to the definition, and
assigns it the default name of CountStar.
column_expression
a valid column expression to be counted.
To avoid overflow, type the COUNT column_expression specification in a join index definition as
FLOAT. If you do not assign a data type, the system types it as FLOAT automatically. If you assign
a type other than FLOAT, the system returns an error message to the requestor.
EXTRACT YEAR |
MONTH FROM
to use the EXTRACT function to extract the year or month from a date expression.
date_expression
a valid date expression from which the year or month is to be extracted.
[AS] expression_alias
a mandatory alias for the aggregated expression.
End Aggregation Clause
SQL Reference: Data Definition Statements
353
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
FROM Clause
FROM database_name.
table_name
the name of a table from which a column or columns to be included in the join index are taken as
well as the name of a table to be joined with at least one other table to form a join index.
You cannot define a join index on any of the following database objects:
•
•
•
•
Global temporary tables
Hash indexes
Join indexes
Journal tables
• Queue tables
• Views (both types)
• Volatile tables
Each table in the FROM clause should have at least one of its fields contained in either
column_1_name or column_2_name.
In the case of a single-table join index, all columns in a FROM clause table must be contained in
the column_1_name list.
Each table name can be qualified by a database name if necessary and can have a maximum of 64
different columns referenced in the entire join index definition.
Every table must be connected to at least one other table by means of a join condition. The cross
join and full outer join conditions are not supported.
The maximum number of table_name references allowed is the same as the system limit for
SELECT statements.
A FROM clause can have any number of simple tables, but is limited to a single joined non-simple
table expression.
For example, the two following examples are legal. The first is a simple table list and the second is
a single non-simple table expression:
FROM table_1, table_2, table_3,
table_4
FROM (table_1 INNER JOIN table_2 ON x1 = x2)
INNER JOIN (table_3 ON x1 = x3)
The following example is not legal because it has more than one non-simple table expression:
FROM (table_1 INNER JOIN table_2
INNER JOIN table_4 ON x3 = x4)
[[AS]
correlation_name]
ON table_1 x1 = x2),(table_3
an alias for table_name.
Joined Table Clause
The joined_table clause is used only for multitable join indexes.
joined_table
the name of a table (or previously joined tables) from which the columns of this join index are to
be derived.
INNER JOIN
keywords defining the join as an ordinary join.
354
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
LEFT OUTER JOIN
keywords defining the join as either a left or a right outer join. Full outer join is not supported for
join indexes.
RIGHT OUTER JOIN
For most non-aggregate applications, this is the better choice for defining a join index.
You cannot specify outer joins for a join index that also contains aggregate operators in its
definition.
When you specify an outer join, the following rules apply:
• The outer table joining column for each condition must be contained in either
column_1_name or column_2_name.
• The inner table of each join condition must have at least one non-nullable column in either
column_1_name or column_2_name.
ON search_condition
a conditional expression used to eliminate all rows from a query that do not evaluate to TRUE.
Multiple join conditions must be connected using the AND logical operator.
Data types for any columns used in a join condition must be drawn from the same domain
because neither explicit nor implicit data type conversions are permitted.
You cannot specify the ROWID keyword in the search condition of a join operation.
[database_name.]
table_name
an optional database name specified if table_name is contained in a database other than the
current database preceding the name of a single table if no tables are joined in this clause.
[[AS]
correlation_name]
an alias for table_name.
End Joined Table Clause
End FROM Clause
WHERE
search_condition
a conditional expression used to eliminate all rows from the SELECT clause query that do not
evaluate to TRUE.
Multiple join conditions must be connected using the AND logical operator.
Data types for any columns used in a join condition must be drawn from the same domain
because neither explicit nor implicit data type conversions are permitted.
You can only specify a join condition using an inequality operator if you specify multiple join
conditions and use the AND logical operator to connect the inequality join condition or
conditions with an equality join condition.
You cannot specify the ROWID keyword in the search condition of a sparse join index definition.
Use caution whenever you define a join index search condition using built-in, or system,
functions because the system resolves their value at the time the join index is created and then
stores it as part of the join index definition. The values are not resolved for built-in functions
specified in a query at the time the Optimizer evaluates the coverage of the index for the query,
which means the Optimizer does not even know the index is relevant if a query specifies the
built-in function used in its index definition instead of specifying the relevant value explicitly (see
“Join Indexes and Built-In Functions” on page 377 for details).
SQL Reference: Data Definition Statements
355
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
WHERE
search_condition
(continued)
The following bullets list the relevant built-in functions:
GROUP BY
column_name
column_position
the name of the column or columns or their ordinal position within the join index definition
select column list used to group aggregate index rows on the AMPs.
•
•
•
•
ACCOUNT
CURRENT_DATE
CURRENT_TIME
CURRENT_TIMESTAMP
•
•
•
•
DATABASE
DATE
PROFILE
ROLE
• SESSION
• TIME
• USER
The GROUP BY column list must include all the nonaggregated columns for an aggregate join
index.
If you include a ROWID column in the GROUP BY column list, it must be previously aliased with
a column name alias. You cannot specify the literal ROWID as part of the column list.
If you specify a GROUP BY clause but do not specify either a COUNT or a SUM operator, then
the system adds a COUNT(*) expression to the column list and names it CountStar.
ORDER BY
column_name
column_position
the name or ordinal position of the column within the join index definition select column list
used to order index rows on the AMPs.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
You cannot specify an ORDER BY clause in the same join index definition as a partitioned
primary index.
Sort order is restricted to ascending. If not specified in the ORDER BY clause, the join index rows
on an AMP are sorted by the row hash of their primary index.
Aggregate columns and expressions are not permitted in the ORDER BY clause.
All ordering column_names must be in the column_name_1 list. Data in column_name is limited
to a maximum of four bytes of the following data types:
• BYTEINT
• DATE
• DECIMAL
• INTEGER
• SMALLINT
End SELECT Clause
356
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
Indexes Clause
The INDEXES clause defines the primary index and any secondary indexes for the join index.
It is used with both multitable and single-table join indexes.
[PRIMARY] INDEX
a mandatory primary index and any number of nonunique secondary indexes defined on the join
index. The primary index for a join index must be a nonunique primary index.
The primary index for an aggregate join index must be drawn from the columns specified in the
GROUP BY clause of the join index definition. You cannot specify any aggregated columns as the
primary index.
You cannot include the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 in the column set that defines the
primary index for a join index, nor can you collect statistics on any of the system-derived
PARTITION columns.
If the primary index is not compressed, you can define it as a partitioned primary index by
specifying a partitioning expression (see “PARTITION BY” on page 357).
You cannot partition the primary index of a join index if the index is defined with compression.
The primary index must be defined as a NUPI even when it is defined on a unique column. You
cannot define a UPI for a join index.
If you do not define an explicit NUPI, then the first column defined for the join index is assigned
to be the NUPI by default.
If you specify one or more NUSIs, each counts against the maximum number of 32 secondary
indexes that can be defined on a join index. Each multicolumn NUSI defined with an ORDER BY
clause counts as two consecutive indexes against the limit of 32 per join index.
PARTITION BY
that the primary index is partitioned by the partitioning expression that follows.
You can define a partitioned primary index for a join index only if the index is not compressed.
You cannot specify a PARTITION BY clause in the same join index definition as an ORDER BY
CLAUSE.
You cannot collect statistics on the system-derived PARTITION column or PARTITION#Ln
columns for a join index.
partitioning_expression
an SQL expression used to define the partition to which a partitioned primary index row is
assigned when it is hashed to its AMP. See “Partitioned and Nonpartitioned Primary Indexes” on
page 718 for more information about partitioned primary indexes.
You can define a multilevel PPI for a noncompressed join index, which means you can define as
many as 15 different partitioning expressions for it. If you do so, you must define at least two
ranges for each level, and each level must be defined by a lone RANGE_N or CASE_N expression.
The result of the partitioning expression is cast to a 4-byte INTEGER type if it is not already of
INTEGER type. The value also must fall within the range 1 - 65 535, inclusive. See “Partitioned
Primary Index For Join Indexes” on page 363 and “Guidelines for Choosing Between a PPI and a
Value-Ordered NUSI For Covering Range Queries With a Join Index” on page 370 for additional
information about PPIs and join indexes.
See SQL Reference: Functions and Operators for documentation of functions that are particularly
useful for use as partitioning expressions, most notably RANGE_N and CASE_N.
SQL Reference: Data Definition Statements
357
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
index_name
the optional name of the NUSI being defined.
ALL
that the defined NUSI is to maintain Row ID pointers for each logical row of the join index (as
opposed to only the compressed physical rows).
ALL also ignores the NOT CASESPECIFIC attribute of data types so a NUSI can include
case-specific values.
ALL enables a NUSI to cover a join index, which enhances performance by eliminating the need
to access the join index when all values needed by a query are in the secondary index. However,
ALL might also require the use of additional index storage space.
Use this keyword only when a secondary index is being defined on top of a join index.
You cannot specify ALL with a PRIMARY index.
You cannot specify multiple indexes that differ only by the presence or absence of the ALL option.
index_column_name
a column set whose values are to be an index on this join index. If you specify more than one
column, then the new index is based on the combined values of each column.
No column in a secondary index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a secondary index.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the index_column_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
If two specified columns have the same name, both names must be aliased with unique column
name aliases. See SQL Reference: Fundamentals.
A maximum of 64 columns can be defined for one index.
Multiple indexes can be defined on the same columns as long as each index differs in its ordering
option (VALUES versus HASH).
358
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
ORDER BY
row ordering on each AMP by a single NUSI column: either value-ordered or hash-ordered.
Each multicolumn NUSI defined with an ORDER BY clause counts as two consecutive indexes
against the limit of 32 per join index.
You cannot specify an ORDER BY clause in the same join index definition as a partitioned
primary index.
Rules for using an ORDER BY clause are shown in the following table:
VALUES
IF you specify ORDER BY …
THEN …
VALUES
column_name_2 must be numeric with four bytes or less
without specifying the HASH or
VALUES keywords
VALUES is assumed by default.
column_name_2
column_name_2 must be one of the columns specified in
the column_name_1 list.
the system-derived PARTITION
column
the request aborts and returns an error to the requestor.
You can specify a user-defined column named partition.
value-ordering for the ORDER BY column. This is the default specification.
Select VALUES to optimize queries that return a contiguous range of values, especially for a
covered index or a nested join.
See “Guidelines for Choosing Between a PPI and a Value-Ordered NUSI For Covering Range
Queries With a Join Index” on page 370 for information about determining whether a PPI or a
value-ordered NUSI would be a better choice for a given application workload.
HASH
hash-ordering for the ORDER BY column.
Select HASH to limit hash-ordering to one column, rather than all columns of the primary index,
which is the default.
Hash-ordering a multicolumn NUSI on one of its columns allows the index to participate in a
nested join where join conditions involve only that ordering column.
SQL Reference: Data Definition Statements
359
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Syntax Element …
Specifies …
column_name_2
a column in the column_name_1 list that specifies the sort order to be used.
No column in a join index can have a UDT, BLOB, or CLOB data type.
You cannot compress column values for a join index.
You cannot specify the system-derived columns PARTITION, PARTITION#L1, PARTITION#L2,
PARTITION#L3, PARTITION#L4, PARTITION#L5, PARTITION#L6, PARTITION#L7,
PARTITION#L8, PARTITION#L9, PARTITION#L10, PARTITION#L11, PARTITION#L12,
PARTITION#L13, PARTITION#L14, or PARTITION#L15 as part of the column_2_name list.
You can, however, specify a user-defined column named PARTITION or PARTITION#Ln, where
n ranges from 1 - 15, inclusive.
Supported data types for a value-ordered, four-bytes-or-less column_name_2 are:
•
•
•
•
•
BYTEINT
DATE
DECIMAL
INTEGER
SMALLINT
End Indexes Clause
ANSI Compliance
CREATE JOIN INDEX is a Teradata extension to the ANSI SQL:2003 standard. ANSI does not
define DDL for creating indexes.
Authorization
You must have the following sets of privileges to create a join index:
•
CREATE TABLE on the database in which the join index is to be created.
•
DROP TABLE or INDEX on each of the covered tables or their containing databases.
Privileges Granted Automatically
Owners have implicit privileges on the join index. The following default privileges are granted
automatically to the creator of a join index:
• DROP TABLE
• RESTORE
• DUMP
• SELECT
• INDEX
360
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Restriction on the Use of the PARTITION Keywords In a Join Index
Definition
The following restrictions apply to the use of the PARTITION and PARTITION#Ln keywords
in a join index definition:
•
You cannot specify any of the following system-derived column names anywhere in a join
index definition:
• PARTITION
• PARTITION#L8
• PARTITION#L1
• PARTITION#L9
• PARTITION#L2
• PARTITION#L10
• PARTITION#L3
• PARTITION#L11
• PARTITION#L4
• PARTITION#L12
• PARTITION#L5
• PARTITION#L13
• PARTITION#L6
• PARTITION#L14
• PARTITION#L7
• PARTITION#L15
•
You cannot collect statistics on any of the system-derived columns listed in the previous
bullet.
•
You can specify a user-created column named PARTITION or PARTITION#Ln, where n
ranges from 1 - 15, inclusive, in the definition of a join index.
•
You can also collect statistics on any user-defined column named PARTITION or
PARTITION#Ln, where n ranges from 1 - 15, inclusive.
There are no restrictions on user-defined columns named PARTITION#Ln, where n ≥ 16,
because there are no system-derived columns within that numeric range.
Restriction on the Use of the ROWID Keyword In a Join Index Definition
You cannot specify the ROWID keyword in the WHERE clause predicate of a sparse join index
or in a join condition within the join index definition.
Because of this restriction, you must drop any join indexes created prior to Teradata Database
V2R6.2 that contain the keyword ROWID in their definition, then recreate them using legal
syntax.
Partitioned Primary Index Tables Are Supported With Join Indexes
You can create join indexes on a table that has either a single-level or multilevel partitioned
primary index.
You can also create either an SLPPI or an MLPPI as the primary index for a noncompressed
join index (see “Partitioned Primary Index For Join Indexes” on page 363 for details).
SQL Reference: Data Definition Statements
361
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Working Around Optimizer Memory Problems Encountered When Creating
Join Indexes for Tables With Partitioned Primary Indexes
If you experience 3710 errors when running queries against a PPI table with a join index, you
can increase the amount of memory that is available to the Optimizer by updating several
DBSControl flags to values that ensure that it can process any request on the PPI table.
The recommended initial settings are as follows:
•
MaxParseTreeSegs = 2,000 for 32-bit systems
= 4,000 for 64-bit systems
•
OptMaxGlobalJI
=8
You might find that your query workloads are such that these values need to be increased still
further.
See Utilities for information about how to change the setting for the MaxParseTreeSegs field in
the DBS Control record. OptMaxGlobalJI is an internal DBSControl field. You must contact a
Teradata support representative to change its value.
See Database Design for information about some special applications of join indexes to PPI
tables.
Distribution of Join Index Rows
The hash distribution of join index rows across the AMPs is controlled by the specified
PRIMARY INDEX clause.
Note that the primary index for a join index must be nonunique: UPIs are never permitted for
join indexes. If you do not define a primary index explicitly, then the first column defined for
the join index is assigned to be its primary index.
By default, rows are sorted locally on each AMP by the hash code of the primary index column
set. To sort by a single column of your choice, use the optional ORDER BY clause in the join
index definition. With the ORDER BY clause, you can sort by raw data values rather than the
default sort on the hash codes for the values.
Sorting a join index NUSI by data values, as opposed to hash codes, is especially useful for
range queries that involve the sort key (see “Guidelines for Choosing Between a PPI and a
Value-Ordered NUSI For Covering Range Queries With a Join Index” on page 370 for a
comparison of value-ordered NUSIs versus SLPPIs for join index range query support).
Value-ordered NUSI storage provides better performance for queries that specify selection
constraints on the value ordering column. NUSI value ordering is limited to a single four-byte
numeric or DATE column.
For example, suppose a common task is to look up sales information by sales date. You can
create a join index on the sales table and order it by sales date. The benefit is that queries that
request sales by sales date only need to access those data blocks that contain the value or range
of values that the queries specify.
362
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
In the following example, the join index rows are hash-distributed across AMPs using c_name
as the (nonunique) primary index and are value-ordered on each AMP using c_custkey as the
sort key:
CREATE JOIN INDEX ord_cust_idx AS
SELECT (o_custkey, c_name), (o_status, o_date, o_comment)
FROM Orders
LEFT JOIN Customer ON o_custkey = c_custkey
ORDER BY o_custkey
PRIMARY INDEX (c_name);
If the join index you are creating is not compressed, then you can define a PPI for it by
specifying one or more partitioning expressions, which also optimizes the access to the index
for range queries on the partitioning column set (see “Partitioned Primary Index For Join
Indexes” on page 363).
Partitioned Primary Index For Join Indexes
PPIs are particularly valuable for optimizing the performance of range queries on the
partitioning column set, but can be neutral or even suboptimal for non-range queries or for
range queries on columns that are not part of the partitioning expression for the join index, so
you should test the performance of PPI join indexes carefully before introducing them to your
production environment.
The following rules apply to specifying a PPI for a join index:
•
You can define both single-level and multilevel PPIs for a join index.
•
A join index on which you define a PPI cannot be compressed.
•
You cannot define both a PARTITION BY and an ORDER BY clause within the same join
index definition.
•
The partitioning columns for an aggregate join index must be drawn from the columns
specified in the GROUP BY clause of the join index definition.
•
You cannot specify an aggregated column as a partitioning column for the PPI.
•
The partitioning expression in a join index acts as a constraint on its underlying base
tables. For an insert, delete24, or update operation on a base table that causes a partition
violation in the join index by making one or more of the partitioning expressions evaluate
to null, the system aborts the request, returns an error message to the requestor, and
neither the base table nor the join index is changed.
Because of the potential for this error occurring, it is essential that you define partitioning
expressions for your PPI join indexes that do not prevent rows from being inserted,
updated, or deleted from the base tables when that is what needs to be done.
Depending on the application, you can use the NO RANGE and UNKNOWN partitions
(see “Purpose and Behavior of the NO RANGE and UNKNOWN Partitions” on page 736)
to specifying partitioning expressions that can deal with such an occurrence gracefully
without aborting the otherwise problematic update25 requests.
24. If a join index definition includes an outer join, deleting base table rows might cause inserts into that join
index for the unmatched rows.
25. Update is used here in its generic sense, meaning any delete, insert, update, or merge operation.
SQL Reference: Data Definition Statements
363
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
You can specify a WHERE clause in the CREATE JOIN INDEX statement to create a sparse
join index for which only those rows that meet the condition of the WHERE clause are
inserted into the index, or, for the case of a row in the join index being updated in such a
way that it no longer meets the conditions of the WHERE clause after the update, cause
that row to be deleted from the index (see “Sparse Join Indexes” on page 377).
The process for this activity is as follows:
a
b
c
The system checks the WHERE clause condition for its truth value after the update to
the row.
IF the condition evaluates to …
THEN the system …
FALSE
deletes the row from the sparse join index.
TRUE
retains the row in the sparse join index and
proceeds to stage b.
The system evaluates the new result of the partitioning expression for the updated row.
IF the partitioning expression …
THEN the system …
evaluates to null or to a value outside the
range 1 through 65,035, inclusive
aborts the request, does not update either the base
table or the sparse join index, and returns an error
message to the requestor.
evaluates to a value between 1 and
65,035, inclusive
stores the row in the appropriate partition, which
might be different from the partition in which it was
previously stored, and continues processing
requests.
End of process.
A sparse join index is also helpful because its WHERE clause is checked first when
maintenance is needed for the join index and the partitioning expression constraint is only
checked if the WHERE clause condition can be satisfied.
You must consider all of the following factors when you are deciding what join indexes to
create to support your workloads:
•
•
364
Data model
•
Table definitions
•
Foreign Key-Primary Key constraints
•
Dimensional hierarchies
Workload
•
Query patterns
•
Query frequencies
•
Query priorities
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
•
Data maintenance
•
Frequency of maintenance
•
Constraints specified by data maintenance statements and commands
You must consider both the advantages and the disadvantages of partitioned primary indexes
and join indexes in order to ensure that you define appropriate join indexes for your
workloads. Use EXPLAIN request modifiers to verify whether your join index is actually used
and to determine whether the system applies any PPI-related optimizations to the query. See
“Example 7: Another SLPPI Join Index” on page 403 for an example of how you might make
some of these determinations.
Expression evaluation errors, such as divide by zero, can occur during the evaluation of a
partitioning expression. The system response to such an error varies depending on the session
mode in effect at the time the error occurs.
IF the session mode is …
THEN the system rolls back the …
ANSI
request that contains the aborted statement.
Teradata
transaction that contains the aborted request.
When you design your partitioning expressions, you should construct them in such a way that
expression errors either cannot, or are very unlikely to, occur.
Use the ALTER TABLE statement to revalidate the primary index of a join index (see “General
Rules for the REVALIDATE PRIMARY INDEX Option” on page 117).
See “Partitioned and Nonpartitioned Primary Indexes” on page 718, “Guidelines and
Restrictions for Partitioned Primary Indexes” on page 726, SQL Reference: Functions and
Operators, and Database Design for additional information about partitioned primary indexes
and the rules and recommendations for using them.
Some Usage Considerations for PPI Join Indexes
Join indexes can improve query response times in the following ways:
•
Multitable join indexes prejoin tables so that the join result is fetched from the join index
directly to answer applicable queries instead of calculating the joins dynamically.
•
Single-table join indexes effectively redistribute the rows in their underlying base table by
choosing a different primary index than the base table to make the joins between the join
index and other tables or indexes more efficient.
You can also use a single-table join index to establish an alternate primary index access
opportunity.
•
Aggregate join indexes preaggregate results so they can be used to answer aggregation
queries directly.
•
Sparse join indexes store a subset of the rows from their underlying base table set based on
a WHERE clause condition. This makes it possible for a smaller join index to be used in
answering queries when applicable.
SQL Reference: Data Definition Statements
365
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Note that a join index can be a combination of the individual types, such as a join index that
has all of the following properties:
•
Sparse
•
Aggregate
•
Multitable
You can create a partitioned primary index for any kind of noncompressed join index.
Therefore, a PPI join index can improve query performance by leveraging both join index and
PPI benefits. The following two scenarios indicate some possibilities in which a
noncompressed join index with a PPI might be beneficial.
Scenario A: Assume a star schema with the following tables in the physical data model:
Dimensional Model Table Type
Fact
Corresponding Physical Table and Column Sets
sales
•
•
•
•
Dimension
sale_date
store_id
prod_id
amount
• calendar
• dayofmth
• mth
• yr
PRIMARY INDEX(yr, mth)
• product
• prod_id
• prod_category
• org
• store_id
• area
• division
• business_unit
366
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
You might want to create an SLPPI aggregate join index with daily summary data to answer
some ad hoc queries for this database schema such as the following:
CREATE JOIN INDEX sales_summary AS
SELECT sale_date, prod_category, division,
SUM(amount) AS daily_sales
FROM calendar AS c, product AS p, org AS o, sales AS s
WHERE c.dayofmth = s.sale_date
AND
p.prod_id = s.prod_id
AND
o.store_id = s.store_id
GROUP BY sale_date, prod_category, division
PRIMARY INDEX(sale_date, prod_category, division)
PARTITION BY RANGE_N(sale_date BETWEEN DATE '1990-01-01'
AND
DATE '2005-12-31'
EACH INTERVAL '1' MONTH);
A wide range of queries can make use of this join index, especially when there exists a foreign
key-to-primary key relationship between the fact table and the dimension tables that enables
the join index to be used broadly to cover queries on a subset of dimension tables (see “Query
Coverage by Join Indexes” on page 384, “Restriction on Coverage by Join Indexes When a Join
Index Definition References More Tables Than a Query” on page 388, and “Rules for Whether
Join Indexes With Extra Tables Cover Queries” on page 391.
A significant performance gain is achieved with this PPI join index when it is used to answer
the queries that have equality or range constraints on the sale_date column.
Optimizations for PPI base tables, such as partition elimination, are applied to a join index in
the same way as they are applied to a base table.
For example, the execution of the following query only needs to access 12 out of 192
partitions, which saves up to 93.75 percent on disk reads, with proportional elapsed time
reductions compared with a corresponding NPPI join index, which must perform a full-table
scan to respond to the same query:
EXPLAIN SELECT prod_category, SUM(amount) AS daily_sales
FROM calendar AS c, product AS p, sales AS s
WHERE c.dayofmth = s.sale_date
AND
p.prod_id = s.prod_id
AND
sale_date BETWEEN DATE '2005-01-01' AND DATE '2005-12-31'
GROUP BY prod_category;
Important phrases in the following report are highlighted in boldface type.
Explanation
---------------------------------------------------------------------1) First, we lock a distinct HONG."pseudo table" for read on a
RowHash to prevent global deadlock for HONG.SALES_SUMMARY.
2) Next, we lock HONG.SALES_SUMMARY for read.
3) We do an all-AMPs SUM step to aggregate from 12 partitions of
HONG.SALES_SUMMARY with a condition of (
"(HONG.SALES_SUMMARY.sale_date >= DATE '2005-01-01') AND
((HONG.SALES_SUMMARY.sale_date <= DATE '2005-12-31') AND
((HONG.SALES_SUMMARY.sale_date >= DATE '2005-01-01') AND
(HONG.SALES_SUMMARY.sale_date <= DATE '2005-12-31')))"), and the
grouping identifier in field 1. Aggregate Intermediate Results
are computed globally, then placed in Spool 3. The size of Spool
3 is estimated with no confidence to be 1 row. The estimated time
for this step is 0.04 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with no confidence
to be 1 row. The estimated time for this step is 0.04 seconds.
SQL Reference: Data Definition Statements
367
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.07 seconds.
Scenario B: With the same schema used in Scenario A, you might sometimes choose to create
an SLPPI single-table join index on the fact table that includes the foreign key of one or more
dimension tables so it can be used to join to the corresponding dimension table set and roll up
to higher aggregate levels. The following is an example of one such single-table join index:
CREATE JOIN INDEX sji AS
SELECT sale_date, prod_id, SUM(amount) AS sales_amount
FROM Sales
GROUP BY sale_date, prod_id
PRIMARY INDEX(sale_date, prod_id)
PARTITION BY RANGE_N(sale_date BETWEEN DATE '1990-01-01'
AND
DATE '2005-12-31'
EACH INTERVAL '1' MONTH);
For a query asking for the total sales amount at the month level, the Optimizer can join this
join index to the calendar table and roll up:
EXPLAIN SELECT yr, mth, SUM(amount)
FROM sales, Calendar
WHERE sale_date=dayofmth
AND sale_date BETWEEN DATE '2005-01-01' AND DATE '2005-12-31'
GROUP BY yr, mth;
Important phrases in the following report are highlighted in boldface type.
Explanation
---------------------------------------------------------------------1) First, we lock a distinct HONG."pseudo table" for read on a
RowHash to prevent global deadlock for HONG.Calendar.
2) Next, we lock a distinct HONG."pseudo table" for read on a RowHash
to prevent global deadlock for HONG.SJI.
3) We lock HONG.Calendar for read, and we lock HONG.SJI for read.
4) We execute the following steps in parallel.
1) We do an all-AMPs RETRIEVE step from HONG.Calendar by way of
an all-rows scan with a condition of (
"(HONG.Calendar.dayofmth <= DATE '2005-12-31') AND
(HONG.Calendar.dayofmth >= DATE '2005-01-01')") into Spool 4
(all_amps), which is duplicated on all AMPs. Then we do a
SORT to order Spool 4 by row hash. The size of Spool 4 is
estimated with no confidence to be 2 rows. The estimated
time for this step is 0.01 seconds.
2) We do an all-AMPs RETRIEVE step from 12 partitions of
HONG.SJI with a condition of ("(HONG.SJI.sale_date >= DATE
'2005-01-01') AND ((HONG.SJI.sale_date <= DATE '2005-12-31')
AND (NOT (HONG.SJI.sale_date IS NULL )))") into Spool 5
(all_amps), which is built locally on the AMPs. Then we do a
SORT to order Spool 5 by row hash. The size of Spool 5 is
estimated with no confidence to be 1 row. The estimated time
for this step is 0.00 seconds.
5) We do an all-AMPs JOIN step from Spool 4 (Last Use) by way of a
RowHash match scan, which is joined to Spool 5 (Last Use) by way
of a RowHash match scan. Spool 4 and Spool 5 are joined using a
merge join, with a join condition of ("sale_date = dayofmth").
The result goes into Spool 3 (all_amps), which is built locally on
the AMPs. The size of Spool 3 is estimated with no confidence to
be 1 row. The estimated time for this step is 0.04 seconds.
6) We do an all-AMPs SUM step to aggregate from Spool 3 (Last Use) by
way of an all-rows scan, and the grouping identifier in field 1.
Aggregate Intermediate Results are computed globally, then placed
in Spool 6. The size of Spool 6 is estimated with no confidence
to be 1 row. The estimated time for this step is 0.05 seconds.
7) We do an all-AMPs RETRIEVE step from Spool 6 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with no confidence
to be 1 row. The estimated time for this step is 0.04 seconds.
368
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
8) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.13 seconds.
Notice that the partition elimination is applied to sji, which reduces the number of rows
accessed to be 12 out of 192 partitions, making the join much faster than it would be with an
otherwise identical NPPI single-table join index, which requires a full-table scan. The system
can apply other PPI-related join optimizations, such as dynamic partition elimination and
Rowkey-Based Merge Join, to PPI join indexes just as they are applied to PPI base tables when
they are found to be applicable.
While a join index can greatly improve the query response time, you must also consider the
overhead of maintaining it when inserts, deletions, and updates are made to the base table on
which the index is defined. A non-compressed PPI join index might experience significant
improvement in its maintenance performance due to PPI-related optimizations. For example,
for the join indexes defined in scenarios A and B, the system can apply partition elimination
when there is an equality or range constraint on the partitioning column in the data
maintenance statement.
For example:
EXPLAIN DELETE sales
WHERE sale_date BETWEEN DATE '1999-01-01'
AND
DATE '1999-12-31';
Important phrases in the following report are highlighted in boldface type.
Explanation
-----------------------------------1) First, we lock a distinct HONG."pseudo table" for write on a
RowHash to prevent global deadlock for HONG.SALES_SUMMARY.
2) Next, we lock a distinct HONG."pseudo table" for write on a
RowHash to prevent global deadlock for HONG.SJI.
3) We lock a distinct HONG."pseudo table" for write on a RowHash to
prevent global deadlock for HONG.sales.
4) We lock HONG.SALES_SUMMARY for write, we lock HONG.SJI for write,
and we lock HONG.sales for write.
5) We execute the following steps in parallel.
1) We do an all-AMPs DELETE from 12 partitions of
HONG.SALES_SUMMARY with a condition of (
"(HONG.SALES_SUMMARY.sale_date >= DATE '1999-01-01') AND
(HONG.SALES_SUMMARY.sale_date <= DATE '1999-12-31')").
2) We do an all-AMPs DELETE from 12 partitions of HONG.SJI with
a condition of ("(HONG.SJI.sale_date >= DATE '1999-01-01')
AND (HONG.SJI.sale_date <= DATE '1999-12-31')").
3) We do an all-AMPs DELETE from HONG.sales by way of an
all-rows scan with a condition of ("(HONG.sales.sale_date >=
DATE '1999-01-01') AND (HONG.sales.sale_date <= DATE
'1999-12-31')").
6) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> No rows are returned to the user as the result of statement 1.
Partitioning on the DATE column in the join index helps insert performance if the transaction
data is inserted into sales according to a time sequence. Note that MultiLoad and FastLoad are
not supported for base tables with join indexes, so other batch loading methods, such as
Teradata Parallel Data Pump or FastLoad into a staging table followed by either an
INSERT … SELECT or MERGE batch request with error logging must be used to load data
into sales. Because the inserted rows are clustered in the data blocks corresponding to the
appropriate partitions, the number of data blocks the system must read and write is reduced
compared with the NPPI join index case where the inserted rows scatter among all the data
blocks.
SQL Reference: Data Definition Statements
369
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Be aware that you cannot drop a join index to enable MultiLoad or FastLoad batch loads until
any requests that access that index complete processing. Requests place READ locks on any
join indexes they access, and the system defers processing of any DROP JOIN INDEX requests
against locked indexes until their READ locks have all been released.
It is also possible for the maintenance of a PPI join index to be less efficient than an otherwise
identical NPPI join index. For example, if the primary index of the join index does not include
the partitioning column set, and a DELETE or UPDATE statement specifies a constraint on
the primary index, the maintenance of the PPI join index must probe all partitions within the
AMP as opposed to the fast primary index access for the NPPI join index.
You must consider all of the following factors when you are deciding what join indexes to
create to support your workloads:
•
•
•
Data model
•
Table definitions
•
Foreign Key-Primary Key constraints
•
Dimensional hierarchies
Workload
•
Query patterns
•
Query frequencies
•
Query priorities
Data maintenance
•
Frequency of maintenance
•
Constraints specified by data maintenance statements and commands
You must consider all of the various tradeoffs between PPIs and join indexes to choose the
optimal join index definitions. Use the EXPLAIN request modifier (see “EXPLAIN Request
Modifier” in SQL Reference: Data Manipulation Statements) to verify if the join indexes you
create are actually selected by the Optimizer and to determine whether the system applies the
various PPI-related optimizations.
Guidelines for Choosing Between a PPI and a Value-Ordered NUSI For
Covering Range Queries With a Join Index
Partitioned primary indexes and value-ordered NUSIs are both designed to optimize the
performance of range queries.26 Because you cannot define both a PPI and a value-ordered
NUSI on the same column set for a join index,27 you must determine which is more likely to
enhance the performance of a given query workload.
You should consider the following guidelines when determining whether to design a join
index for a particular workload using a PPI on the join index or using an NPPI and adding a
value-ordered NUSI to create a value-ordered access path to the rows:
26. Note that these guidelines apply to choosing between a value-ordered NUSI and an SLPPI only.
Value-ordered NUSIs are not an alternative to MLPPIs.
27. Nor can you define a PPI for a compressed join index.
370
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
•
The most general guideline is that if you can achieve what you need to achieve using a PPI
on the join index, then you should do that rather than using a value-ordered NUSI and an
NPPI on the join index.
•
If compression is defined on the join index, then you cannot define a PPI for it.
For this scenario, a value-ordered NUSI is your only join index design choice possibility
for optimizing range queries.
•
Each time an underlying base table for a join index is updated, the join index, too, must be
updated.
If there is a value-ordered NUSI defined on a join index, then it, too, must be updated each
time the base table (and join index) rows are updated.
This additional maintenance is avoided entirely when you define the join index with a PPI,
and partition elimination makes updating28 a PPI join index even faster than the
equivalent update operation against an NPPI join index.
•
All things being equal, a PPI offers the benefit of providing direct access to join index rows,
while a value-ordered NUSI does not.
Using a NUSI to access rows is always an indirect operation, accessing the NUSI subtable
before being able to go back to the join index to access a row set; however, if the NUSI
covers the query, there is no need to access the rows in the join index subtable.
Beside offering a direct path for row access, a PPI also provides a means for attaining better
join and aggregation strategies on the primary index of the join index.
•
If the primary index is specified as a query condition, a PPI offers the additional benefit of
enhanced direct join index row access using partition elimination rather than the
all-AMPs access approach required by NUSIs.
Ultimately, however, the comparative row access time depends on the selectiviity of a
particular value-ordered NUSI, the join index row size, and whether a value-ordered NUSI
covers a given query or not.
•
If a join index column has more than 65 535 unique values, and the query workload you
are designing the index for probes for a specific value, then a value-ordered NUSI is likely
to be more selective than a join index partitioned on that column.
28. The word update is used in its generic sense to include the delete, and update (but not insert) operations
performed by DELETE, MERGE, and UPDATE SQL statements.
Note that a PPI can improve insert performance, too, if the inserted rows are clustered in the data blocks
that correspond to the partitions. In this case, the number of data blocks read and written is reduced
compared with the NPPI join index case where the inserted rows scatter among all the data blocks.
SQL Reference: Data Definition Statements
371
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Disk I/O Integrity Checking
The Teradata Database permits you to select various levels of disk I/O integrity checking of
your table data using one of the following integrity checks ranked in order of their ability to
detect errors:
1
Full end-to-end checksums (ALL)
Detects most bit, byte, and byte string errors.
2
Statistically sampled partial end-to-end checksums (LOW, MEDIUM, HIGH)
Detects lost writes and intermediate levels of bit, byte, and byte string errors.
3
Disable checksum disk I/O integrity checks. (NONE)
Detects some forms of lost writes using standard file system metadata verification.
The checksum setting applies to primary data rows, fallback data rows, and all secondary
index rows for the join index.
This feature detects and logs disk I/O errors: it does not repair them.
The more words used to generate the checksum value, the better able that checksum is to
detect disk I/O errors. Because CPU utilization increases as a function of the number of words
used to generate a checksum, several different levels of checking are provided so you can
adjust disk I/O integrity checking at the level of individual tables as needed, balancing
integrity checking against system performance.
You can specify system-wide checksum defaults for various table types using the Checksum
Levels fields of the DBSControl utility Disk I/O Integrity fields and you can specify the
system-wide checksum level definitions for the LOW, MEDIUM, and HIGH values using the
Checksum Level Definitions fields of the DBSControl utility Disk I/O Integrity fields. See
Utilities and Database Administration for details.
Rules for Using the ROWID Keyword in a Join Index Definition
The ROWID keyword can only be used in a join index definition. The rules for using ROWID
in a join index definition are as follows:
•
You can optionally specify the ROWID for a base table in the select list of a join index
definition.
If you reference multiple tables in the join index definition, then you must fully qualify
each ROWID specification.
•
You can reference a column name alias for ROWID, or the keyword ROWID itself if no
column name alias has been specified for it, in the primary index definition or in a
secondary index defined for the join index in its index clause.
This does not mean that you can reference a ROWID or its column name alias in a
secondary index defined separately with a CREATE INDEX statement (see “CREATE
INDEX” on page 336) after the join index has been created.
372
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
•
If you reference a ROWID column name alias in the select list of a join index definition,
then you can also reference that column name alias in a CREATE INDEX statement that
creates a secondary index on the join index.
•
Column name aliases are required to resolve any column name or ROWID ambiguities in
the select list of a join index definition.
An example is the situation where you specify ROWID for more than one base table in the
index definition.
Similarities and Differences Between Join Indexes and Base Tables
In many respects, a join index is similar to a base table. For example, you can create NUSIs on
a join index and you should collect statistics on appropriate columns and indexes of both to
ensure that the Optimizer has accurate statistical summaries of their demographics.
You can also perform DROP, HELP and SHOW statements on join indexes; however, you
cannot directly query or update a join index.29
For example, the following query is not valid because ord_cust_idx is a join index, not a base
table:
SELECT o_status, o_date, o_comment
FROM ord_cust_idx;
Because join indexes are not part of the logical definition of a database, you can use them as
summary and prejoin tables, both of which would otherwise violate the rules of
normalization. The update anomalies presented by denormalized structures like summary
and prejoin tables are avoided because the system implicitly performs all necessary updates to
join indexes to ensure that no information is ever lost and that semantic integrity is always
enforced (see “Join Index Updates Are Maintained by the System” on page 373 for details).
Join Index Updates Are Maintained by the System
Join indexes are automatically maintained by the system when update operations (DELETE,
INSERT, MERGE, UPDATE) are performed on columns in their underlying base tables that
are also defined for the join index. Additional steps are included in the execution plan to
regenerate the affected portion of the stored join result.
29. You can do this by creating a view that has a similar definition to that of the join index, which can then be
queried like any other view. Such a view provides a logical view of the data, and you can maintain it for as
long as you need it. A join index, in contrast, is a physical database object that you create or delete for
performance reasons. It does not affect the logical view of the data in any way.
SQL Reference: Data Definition Statements
373
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Simple Join Indexes
Define a simple join index as a join index that does not specify aggregate operations.
The primary function of a simple join index is to provide the Optimizer with a performant,
cost-effective means for satisfying any query that specifies a frequently performed join
operation. The simple join index permits you to define a permanent prejoin table without
violating schema normalization.
You can also define a simple join index on a single table. This permits you to hash a subset of
the columns of a large replicated base table on a foreign key that hashes rows to the same AMP
as another large table to which it is frequently joined.30 In some situations, this is more
performant than building a multitable join index on the same columns. The advantage comes
from less internal update maintenance on the single table form of the index. Only prototyping
can determine which is the better design for a given set of tables, applications, and hardware
configuration.
The following describes a general procedure for defining a single-table join index:
1
Determine whether the primary index for the join index should be an NPPI or a PPI.
If you decide to define the index using a PPI, determine whether that PPI should be a
single-level or multilevel PPI.
2
Define a join index on the frequently joined columns of the table to be distributed on a
new primary index.
3
Define a column_1_name for each column_name in the primary base table to be included
in the single-table join index.
Include the keyword ROWID as a value in the column_name list31 to enable the Optimizer
to join a partial covering index to its base table to access any noncovered columns.
Even though you do not explicitly specify this join when you write your query, it counts
against the 64 table restriction on joins.
4
Define the primary index on the column set on which the join is made. This is typically a
foreign key from the table to which the index table is to be joined.
5
If performance suggests it, use CREATE INDEX to create one or more NUSIs on the join
index.
6
If performance suggests it, collect the appropriate statistics on the join columns, the
indexes, and the ORDER BY column. In most applications, you should collect statistics on
the base table columns on which the index is defined rather than on the index columns
themselves. See “Collecting Statistics on a Single-Table Join Index” on page 379 and
“Collecting Statistics on Base Table Columns Instead of Single-Table Join Index Columns”
on page 380 for clarification.
7
End of procedure.
30. This is most commonly done by projecting a proper subset of the columns from the base table into a
single-table join index, which is often referred to as vertical partitioning (note that the partitioning here
has nothing to do with the sort of range partitioning performed with a partitioned primary index), but if
your design requires it, you can also project all of the columns from the base table into a second physical
table that differs from its underlying base table only in the way its rows are hashed to the AMPs.
31. You can only specify ROWID in the outermost SELECT of the CREATE JOIN INDEX statement.
374
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Aggregate Join Indexes
Define an aggregate join index as a join index that specifies SUM or COUNT aggregate
operations. No other aggregate functions are permitted in the definition of a join index.
To avoid numeric overflow, the COUNT and SUM fields in a join index definition must be
typed as FLOAT. If you do not assign a data type to COUNT and SUM, the system types them
as FLOAT automatically. If you assign a type other than FLOAT, an error message occurs.
If you define a PPI for an aggregate join index, then its partitioning columns must be
members of the column set specified in the GROUP BY clause of the index definition. In other
words, you cannot specify an aggregated column as a partitioning column.
The primary function of an aggregate join index is to provide the Optimizer with a
performant, cost-effective means for satisfying any query that specifies a frequently made
aggregation operation on one or more columns. The aggregate join index permits you to
define a summary table without violating schema normalization.
Optimizer Rules for Using Aggregate Join Indexes in a Query Plan
The Optimizer analyzes all queries for the use of an aggregate join index. In determining if an
aggregate join index can be used to process a query, the Optimizer applies the following rules:
•
An aggregate join index cannot be used to substitute for the base tables of a nonaggregate
query.
•
Like a simple join index, an aggregate join index qualifies for inclusion in the plan if it
specifies either the same joins or a subset of the joins of the query.
•
If an aggregate join index specifies a subset of joins of the query, then all the joined fields
of the remaining join conditions on the tables of the aggregate join index must be specified
in the GROUP BY clause and in the select list of the aggregate join index definition.
•
Even if an aggregate join index specifies the same joins as the query, it does not qualify if its
GROUP BY columns are neither the same nor a superset of the GROUP BY columns for
the query.
•
An aggregate join index must contain all the columns needed by the query for the tables
that it replaces. When trying to match expressions from a query to the select list for a join
index, the Optimizer applies the following rules:
•
Addition and multiplication are commutative.
•
COUNT(*) and COUNT(non-null_expression) are used interchangeably.
•
A numeric expression from the join index that is converted to FLOAT can be used to
match any expression of the same type defined with or without the conversion from
the query.
•
An AVERAGE aggregate expression in a query is converted to a SUM/COUNT
expression when an aggregate join index substitutes for it.
•
A SUM(0) expression in a query is converted to a constant having value 0.
•
A SUM(constant) expression in a query matches with constant * COUNT(*) in a
aggregate join index definition.
SQL Reference: Data Definition Statements
375
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
•
The SUM or COUNT function from SUM(CASE expression) or COUNT(CASE
expression) can be pushed to all the resulting expressions of the CASE expression in
order to find a match. For example, the following expression can be converted to the
expression following it in order to find a match:
SUM(CASE WHEN x1=1
THEN 1
ELSE 0)
CASE WHEN x1=1
THEN SUM(1)
ELSE SUM(0)
•
Conditions are converted according to the following conversion table:
THIS condition …
IS converted to this equivalent expression …
expression >= ‘YYYY0101’
‘EXTRACT(YEAR FROM expression) >= YYYY’
expression > ‘YYYY1231’
‘EXTRACT(YEAR FROM expression) > YYYY’
expression < ‘YYYY0101’
‘EXTRACT(YEAR FROM expression) < YYYY’
expression <= ‘YYYY1231’
‘EXTRACT(YEAR FROM expression) <= YYYY’
expression >= ‘YYYYMM01’
‘EXTRACT(YEAR FROM expression) > YYYY’
or
‘(EXTRACT(YEAR FROM expression) = YYYY AND
EXTRACT(MONTH FROM expression) >= MM)’
expression > ‘YYYYMMLD’
‘EXTRACT(YEAR FROM expression) > YYYY’
where LD is the last day of the
month specified by MM
or
‘(EXTRACT(YEAR FROM expression) = YYYY
AND
EXTRACT(MONTH FROM expression) > MM)’
expression <= ‘YYYYMMLD’
‘EXTRACT(YEAR FROM expression) < YYYY’
where LD is the last day of the
month specified by MM
or
expression < ‘YYYYMM01’
‘(EXTRACT(YEAR FROM expression) =YYYY AND
EXTRACT(MONTH FROM expression) <= MM)’
‘EXTRACT(YEAR FROM expression) < YYYY’
or
‘(EXTRACT(YEAR FROM expression) = YYYY AND
EXTRACT(MONTH FROM expression) < MM)’
376
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Sparse Join Indexes
You can create join indexes that restrict the number of rows in the index to those that are
accessed when, for example, a frequently run query references only a small, well known subset
of the rows of a large base table. By using a constant expression in the WHERE clause to filter
the rows included in the join index, you can create what is known as a sparse index.
For example, the following DDL creates an aggregate join index containing only the sales
records from 2005:
CREATE JOIN INDEX j1 AS
SELECT storeid, deptid, SUM(sales_dollars)
FROM sales
WHERE EXTRACT(year, sales_date) = 2007
GROUP BY storeid, deptid;
When a request is made against an indexed base table, the Optimizer determines if accessing j1
gives the correct answer and is more efficient than accessing the base tables. The Optimizer
then selects this sparse join index only for queries that restricted themselves to data from the
year 2007.
For example. a query might require data from departments 42, 43, and 44, but only for the
year 2007. Because the join index j1 contains all of the data for year 2007, it might be used to
satisfy the following query:
SELECT storeid, deptid, SUM(sales_dollars)
FROM sales
WHERE EXTRACT(year FROM sales_date) = 2007
AND deptid IN(42, 43, 44)
GROUP BY storeid, deptid;
See Database Design for applications of sparse join indexes that take advantage of a partitioned
primary index on the base table they support.
Join Indexes and Built-In Functions
When you create a join index that specifies a built-in, or system, function in its WHERE clause
(see SQL Reference: Functions and Operators for more information about built-in functions),
the system resolves the function at the time the join index is created and then stores the result
as part of the index definition rather than evaluating it dynamically at the time the Optimizer
would use the index to build a query plan.
As a result, the Optimizer does not use a join index in the access plan for a query that qualifies
its WHERE clause with the same built-in function used to define that join index because it
cannot determine whether the index covers the query or not. The Optimizer does use the join
index if the query specifies an explicit value in its WHERE clause that matches the resolved
value stored in the index definition.
For example, suppose you decide to define a join index using the CURRENT_DATE built-in
function on January 4, 2007 as follows:
CREATE JOIN INDEX curr_date AS
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
SQL Reference: Data Definition Statements
377
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
On January 7, 2007, you perform the following SELECT statement:
SELECT *
FROM orders
WHERE order_date = CURRENT_DATE;
When you EXPLAIN this query, you find that the Optimizer does not use join index curr_date
because the date stored in the index definition is the explicit value ‘2007-01-04’, not the
current system date ‘2007-01-07’.
On the other hand, if you were to perform the following SELECT statement on January 7,
2007, or any other date, the Optimizer does use join index curr_date for the query plan
because the statement explicitly specifies the same date that was stored with the join index
definition when it was created:
SELECT *
FROM orders
WHERE order_date = DATE ‘2007-01-04’;
Outer Joins and Simple Join Indexes
Because join indexes generated from inner joins do not preserve unmatched rows, you should
always consider using outer joins to define simple join indexes. This practice empowers the
join index to satisfy queries with fewer join conditions than those used to generate the index.
You can define a join index using both left and right outer joins, but full outer joins are
prohibited.
Be aware that when you define a join index using an outer join, you must reference all the
columns of the outer table in the select list of the join index definition. If any of the outer table
columns are not referenced in the select list for the join index definition, the system returns an
error to the requestor.
See “Restriction on Coverage by Join Indexes When a Join Index Definition References More
Tables Than a Query” on page 388 and “Rules for Whether Join Indexes With Extra Tables
Cover Queries” on page 391 for some special considerations about how to define outer joins
to maximize the coverage possibilities of a join index.
Outer Joins and Aggregate Join Indexes
Outer joins are not permitted in aggregate join index definitions.
Collecting Statistics on Join Indexes
Single- and multitable join indexes are fundamentally different database objects in many ways,
and they are used for different purposes.
As with hash indexes, column statistics for single-table join indexes are often best collected
directly on the base table columns rather than separately as is always required for multitable
join indexes.
You cannot collect statistics on the system-derived PARTITION columns of a PPI join index.
This restriction includes the PARTITION#Ln column set derived for MLPPI join indexes,
where n ranges between 1 and 15, inclusive.
378
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
The following table points to the various topics that explain the different recommendations
for collecting statistics for single-table and multitable join indexes:
FOR this type of
join index …
The following topics explain how best to collect statistics on the index …
single-table
• “Collecting Statistics on a Single-Table Join Index” on page 379.
• “Collecting Statistics on Base Table Columns Instead of Single-Table Join
Index Columns” on page 380.
• “Guidelines for Collecting Statistics On Single-Table Join Index Columns” on
page 381.
multitable
“Collecting Statistics on Multitable Join Indexes” on page 382.
sparse
• “Collecting Statistics on a Single-Table Join Index” on page 379.
• “Collecting Statistics on Base Table Columns Instead of Single-Table Join
Index Columns” on page 380.
For general information about collecting statistics, see “COLLECT STATISTICS (Optimizer
Form)” on page 1292).
You can use the Teradata Statistics Wizard client utility to determine which indexes best
support a join index for a specified SQL query workload. See Teradata Statistics Wizard User
Guide for further information about the Teradata Statistics Wizard.
Collecting Statistics on a Single-Table Join Index
As is true for hash indexes, you should collect the statistics on base table columns rather than
on single-table join index columns for most applications.
Note: If the join index is sparse (see “Sparse Join Indexes” on page 377), you should collect
statistics on the join index itself rather than on its underlying base table.
See “Collecting Statistics on Base Table Columns Instead of Single-Table Join Index Columns”
on page 380 for further information.
You can collect and drop statistics on the primary index columns of a single-table join index
using an INDEX clause to specify the column set.
For example, suppose a join index has the following definition:
CREATE JOIN INDEX OrdJIdx8 AS
SELECT o_custkey, o_orderdate
FROM Orders
PRIMARY INDEX (o_custkey, o_orderdate)
ORDER BY (o_orderdate);
Then you can collect statistics on the index columns as a single object as shown in the
following example:
COLLECT STATISTICS ON OrdJIdx8 INDEX (o_custkey, o_orderdate);
Note that you can only use columns specified in a multicolumn PRIMARY INDEX clause
definition if you specify the keyword INDEX in your COLLECT STATISTICS request.
SQL Reference: Data Definition Statements
379
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
A poorer choice would be to collect statistics using the column clause syntax. To do this, you
must perform two separate statements:
COLLECT STATISTICS ON OrdJIdx8 COLUMN (o_custkey);
COLLECT STATISTICS ON OrdJIdx8 COLUMN (o_orderdate);
It is always better to collect the statistics for multicolumn indexes32 on the index itself rather
than individually on its component columns because its selectivity is much better when you
collect statistics on the index columns as a set.
For example, a query with a condition like WHERE x=1 AND y=2 is better optimized if
statistics are collected on INDEX (x,y) than if they are collected individually on column x and
column y.
The same restrictions hold for the DROP STATISTICS statement.
Collecting Statistics on Base Table Columns Instead of Single-Table Join
Index Columns
The Optimizer substitutes base table statistics for single-table join index statistics when no
demographics have been collected for its single-table indexes. Because of the way single-table
join index columns are built, it is generally best not to collect statistics directly on the index
columns and instead to collect them on the corresponding columns of the base table. This
optimizes both system performance and disk storage by eliminating the need to collect the
same data redundantly.
Note: This recommendation is not true for sparse join indexes (see “Sparse Join Indexes” on
page 377). If the join index is sparse, you should collect statistics on the join index itself rather
than on its underlying base table.
There are three reasons why you might need to collect statistics on single-table join index
columns instead of their underlying base table columns.
•
The single-table join index is sparse (see “Sparse Join Indexes” on page 377).
•
If you decide not to collect the statistics for the relevant base table columns for some
reason, then you should collect them directly on the corresponding single-table join index
columns.
•
If the primary index column set consists of more than one column, and there is no
primary or secondary index on the base table that includes those columns, then you have
two options:
•
The better option is to collect multiple column statistics on the base table (see
“Collecting Statistics on Multiple Columns” on page 1312).
•
A much poorer option is to collect the statistics on the column set for the single-table
join index. If you do this, you must use the COLLECT STATISTICS ON … INDEX
syntax to collect the statistics for that column set on the single-table join index.
32. Note that you can collect statistics on multiple non-indexed columns as well. See “Collecting Statistics on
Multiple Columns” on page 1312.
380
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Guidelines for Collecting Statistics On Single-Table Join Index Columns
The guidelines for selecting single-table join index columns on which to collect statistics are
similar to those for base tables and hash indexes. The primary factor to consider in all cases is
whether the statistics provide better access plans. If they do not, consider dropping them. If
the statistics you collect produce worse access plans, then you should always report the
incident to Teradata support personnel.
When you are considering collecting statistics for a single-table join index, it might help to
think of the index as a special kind of base table that stores a derived result. For example, any
access plan that uses a single-table join index must access it with a direct probe, a full table
scan, or a range scan.
With this in mind, consider the following factors when deciding which columns to collect
statistics for:
•
Always consider collecting statistics on the primary index. This is particularly critical for
accurate cardinality estimates.
•
IF an execution plan might involve …
THEN collect statistics on the …
search condition keys
column set that constitutes the search condition.
joining the single-table index with
another table
join columns to provide the Optimizer with the
information it needs to best estimate the
cardinalities of the join.
IF a single-table join index is defined …
THEN you should collect statistics on the …
with an ORDER BY clause
order key specified by that clause.
without an ORDER BY clause and the
order key column set from the base table
is not included in the column_name_1 list
order key of the base table on which the index is
defined.
•
•
This action provides the Optimizer with several
essential baseline statistics.
If a single-table join index column appears frequently in WHERE clauses, you should
consider collecting statistics on it as well, particularly if that column is the sort key for a
value-ordered single-table join index.
SQL Reference: Data Definition Statements
381
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Collecting Statistics on Multitable Join Indexes
Statistics for multitable join indexes and the base tables they index are not interchangeable.
Whenever a column is defined both for the base table and for a multitable join index defined
on it, you must collect statistics separately on both columns.
The demographics for column values stored in a base table are often very different than those
stored for a derived join result in a multitable join index. When statistics have not been
collected on a multitable join index, the Optimizer does not derive corresponding statistics
from the statistics collected on its underlying base tables.
You can collect statistics on a simple data column or secondary index column set of a join
index. It is instructive to think of a multitable join index as a special base table representing a
derived join result. You might need to collect statistics on search condition keys to help the
Optimizer to evaluate alternative access paths.
Execution plans can also involve joining a multitable join index table with yet another table
that is not part of the multitable join index. When your EXPLAIN statements indicate that this
is happening, you should also collect statistics on those join columns to help the Optimizer to
estimate cardinalities.
Before creating a new multitable join index, you should consider performing the following
procedure in order to improve the performance of its creation as well as its update
maintenance:
1
Collect statistics on the base tables underlying the planned multitable join index.
2
Immediately create the new multitable join index.
3
End of procedure.
Compression of Join Index Rows
The term compression is used to mean two entirely different things for the Teradata system.
Both forms are lossless, meaning that the original data can be reconstructed exactly from their
compressed forms:
•
When describing compression of hash and join indexes, compression refers to a logical
row compression in which multiple sets of nonrepeating column values are appended to a
single set of repeating column values. This allows the system to store the repeating value
set only once, while any nonrepeating column values are stored as logical segmental
extensions of the base repeating set.
•
When describing compression of column values, compression refers to the storage of those
values one time only in the table header, not in the row itself, and pointing to them by
means of an array of presence bits in the row header. The method is called Dictionary
Indexing, and it can be viewed as a variation of Run-Length Encoding (see Database
Design for additional information).
This topic refers to the first definition of compression in the preceding list.
The storage organization for join indexes supports a compressed format to reduce storage
space.33
382
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
If you know that a join index contains groups of rows with repeating information, then its
definition DDL can specify repeating groups, indicating the repeating columns in parentheses.
The column list is specified as two groups of columns, with each group stipulated within
parentheses. The first group contains the repeating columns and the second group contains
the non-repeating columns.
Note that you cannot define both compression and a partitioned primary index for the same
join index.
Physical Join Index Row and Compression
A physical join index row has two parts:
•
A required fixed part that is stored only once.
•
An optional repeated part that is stored as often as needed.
For example, if a logical join result has n rows with the same fixed part value, then there is one
corresponding physical join index row that includes n repeated parts in the physical join
index. A physical join index row represents one or more logical join index rows. The number
of logical join index rows represented in the physical row depends on how many repeated
values are stored.
Compression is only done on rows inserted by the same INSERT statement. This means that
newly inserted rows are not added as logical rows to existing compressed rows.
When the number of repeated values associated with a given fixed value exceeds the system
row size limit, the join index row is automatically split into multiple physical rows, each
having the same fixed value but different lists of repeated values. Note that a given logical join
index result row cannot exceed the system 64K row size limit.
Guidelines for Using Compression With Join Index Columns
A column set with a high number of distinct values cannot be compressed because it rarely
(and in the case of a primary key or unique index, never) repeats. Other column sets, notably
foreign key and status code columns, are generally highly nondistinct: their values repeat
frequently. Compression capitalizes on the redundancy of frequently repeating column values
by storing them once in the fixed part of the index row along with multiple repeated values in
the repeated part of the index row.
Typically, primary key table column values are specified as the repeating part and foreign key
table columns are specified in the fixed part of the index definition.
See Database Design for more information about compressing join indexes.
33. Join indexes do not inherit column value compression from their underlying base tables, nor do they
support column value compression.
SQL Reference: Data Definition Statements
383
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Query Coverage by Join Indexes
When the columns requested by a query can be retrieved from an index instead of scanning
the base table that index supports, the index is said to cover the query. Some vendors refer to
this as index-only access. Although secondary indexes can sometimes cover a minor query,
only hash and join indexes are generally called upon to respond to queries of any consequence.
If a join index is defined correctly, it can also cover a query that requests columns it does not
carry. This situation is called partial query coverage, and when a join index partially covers the
query, the Optimizer can weigh the cost of using it against the cost of scanning the base table
set it supports. The criteria for defining a join index to make it eligible for consideration as a
partial query cover are described in the following paragraphs.
Other, more complicated, criteria for determining whether a join index can cover a query are
described in “Restriction on Coverage by Join Indexes When a Join Index Definition
References More Tables Than a Query” on page 388, and “Rules for Whether Join Indexes
With Extra Tables Cover Queries” on page 391.
See Database Design for information about using global join indexes with tactical queries.
A join index that has the capability of accessing base table columns via a prime access key
specified in its definition DDL is eligible for partial query covering. A join index defined in
this way is sometimes referred to as a global index or a global join index.
Support for global join indexes is provided by the following substitution logic:
IF the definition for a single-table join index …
THEN that join index …
specifies any one or more of the following items:
qualifies as a partial covering index if it also
contains a subset of the columns specified by a
query.
• ROWID keyword as a column name in the
column_name lista
• Column set that defines the UPI of the
underlying base table
• Column set that defines the NUPI of the
underlying base table plus the ROWID
keyword
• Column set that defines the NUPI of the
underlying base table plus a column set that
defines a USI on the underlying base table
does not specify the ROWID keyword, base
table UPI columns, or base table NUPI columns
plus either the ROWID keyword or a base table
USI column set
Partial coverage is not restricted to single-table
join indexes.
Join indexes defined with one of these column
sets are sometimes referred to as global indexes
or global join indexes. See Database Design for
some specific applications of global join indexes.
The Optimizer specifies a join from the join
index to the base table to pick up columns that
are requested by the query but not included in
the single-table join index definition.
cannot be used to partially cover a query.
a. You can only specify ROWID in the outermost SELECT of the CREATE JOIN INDEX statement.
The Optimizer specifies a join from the join index to the base table to pick up columns that
are requested by the query but not included in the join index.
384
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
IF this item is specified in the join
index definition …
THEN the join from the single-table join index to the base table is
made using this join type …
the base table ROWID onlya
Row ID
the base table primary index
Merge
In this case, both the primary index column set and the
ROWID, if present, are used to make the join.
a. You can only specify ROWID in the outermost SELECT of the CREATE JOIN INDEX statement.
Even though you do not explicitly specify this join when you write your query, it counts
against the 64 tables per query block restriction on joins.
IF this item is specified in
the join index definition …
THEN it is …
UPI
not necessary to include ROWID in the index definition to enable it as
a partial cover because a UPI is sufficient to identify any base table
row.a
NUPI
necessary to include either of the following specifications to make it
eligible for partial coverage of a query.
• The base table NUPI column set and ROWID in the index
definition.
• The base table NUPI column set and a base table USI column set in
the index definition.
The NUPI plus ROWID option is the preferable choice.
a. You can only specify ROWID in the outermost SELECT of the CREATE JOIN INDEX statement.
The Optimizer specifies a partially covering join index in a join plan only if the cost of using it
is less than the cost of not using it, just as it does for an index that fully covers the query.
For example, consider the following table and join index definitions:
CREATE TABLE t1 (
x1 INTEGER,
y1 INTEGER,
z1 INTEGER)
PRIMARY INDEX (x1);
CREATE TABLE t2 (
x2 INTEGER,
y2 INTEGER,
z2 INTEGER)
PRIMARY INDEX (x2);
CREATE JOIN INDEX j1 AS
SELECT y1
FROM t1
PRIMARY INDEX (y1);
SQL Reference: Data Definition Statements
385
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
The Optimizer selects single-table join index j1 as a partial covering index for its join plan for
the following query.
EXPLAIN
SELECT x1, y1, z2
FROM t1, t2
WHERE y1 = x2
AND
y2 = 1;
*** Help information returned. 29 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct STJI."pseudo table" for read on a
RowHash to prevent global deadlock for STJI.j1.
2) Next, we lock a distinct STJI."pseudo table" for read on a RowHash
to prevent global deadlock for STJI.t2.
3) We lock a distinct STJI."pseudo table" for read on a RowHash to
prevent global deadlock for STJI.t1.
4) We lock STJI.j1 for read, we lock STJI.t2 for read, and we lock
STJI.t1 for read.
5) We do an all-AMPs JOIN step from STJI.t2 by way of a RowHash match
scan. with a condition of ("STJI.t2.y2 = 1"), which is joined to
STJI.j1. STJI.t2 and STJI.j1 are joined using a merge join, with
a join condition of ("STJI.j1.y1 = STJI.t2.x2"). The input table
STJI.j1 will not be cached in memory. The result goes into Spool
2, which is redistributed by hash code to all AMPs. Then we do a
SORT to order Spool 2 by field Id 1. The size of Spool 2 is
estimated with no confidence to be 1 row. The estimated time for
this step is 0.06 seconds.
6) We do an all-AMPs JOIN step from Spool 2 (Last Use) by way of an
all-rows scan, which is joined to STJI.t1. Spool 2 and STJI.t1
are joined using a row id join, with a join condition of (
"Field_1 = STJI.t1.RowID"). The input table STJI.t1 will not be
cached in memory. The result goes into Spool 1, which is built
locally on the AMPs. The size of Spool 1 is estimated with no
confidence to be 1 row. The estimated time for this step is 0.20
seconds.
7) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.26 seconds.
In this query, joining tables t1 and t2 would require redistributing all the t1 rows by t1.y1. This
is an expensive operation if t1 is very large.
An alternative, more cost-effective solution is to perform a local join between join index j1
and base table t2 and then to redistribute the intermediate join result to join with base table t1.
Since there is a precise constraint condition on base table t2 that t2.y2 = 1, redistributing the
join result of j1 and t2 and then joining the result to t1 is less expensive than the redistribution
cost of t1. Therefore, the Optimizer selects j1 to process the t1-t2 join.
By contrast, consider a similar query without the t2.y2 = 1 constraint. In this case, the
Optimizer does not select j1 to cover the query even though it qualifies as a partially covering
index:
INSERT SELECT x1, y1, z2
FROM t1,t2
WHERE y1 = x2;
*** Help information returned. 22 rows.
*** Total elapsed time was 1 second.
386
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct STJI."pseudo table" for read on a
RowHash to prevent global deadlock for STJI.t2.
2) Next, we lock a distinct STJI."pseudo table" for read on a RowHash
to prevent global deadlock for STJI.t1.
3) We lock STJI.t2 for read, and we lock STJI.t1 for read.
4) We do an all-AMPs RETRIEVE step from STJI.t1 by way of an all-rows
scan with a condition of ("NOT (STJI.t1.y1 IS NULL)") into Spool 2,
which is redistributed by hash code to all AMPs. Then we do a
SORT to order Spool 2 by row hash. The size of Spool 2 is
estimated with low confidence to be 101 rows. The estimated time
for this step is 3 minutes and 9 seconds.
5) We do an all-AMPs JOIN step from STJI.t2 by way of a RowHash match
scan., which is joined to Spool 2 (Last Use). STJI.t2 and Spool 2
are joined using a merge join, with a join condition of ("y1 =
STJI.t2.x2"). The result goes into Spool 1, which is built
locally on the AMPs. The size of Spool 1 is estimated with no
confidence to be 3 rows. The estimated time for this step is 0.18
seconds.
6) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 3 minutes and 9 seconds.
Restriction on Partial Coverage of Outer Join Queries by Compressed Join
Indexes
Compressed join indexes (see “Compression of Join Index Rows” on page 382 and “Physical
Join Index Row and Compression” on page 383) cannot be used to partially cover an outer
join query block. This is true for both single-table and multitable join indexes.
For example, suppose you have the following join index definition:
CREATE JOIN INDEX no_outerj_cov AS
SELECT (custkey), (orderkey, orderstatus, o_comment)
FROM cust LEFT OUTER JOIN ordertbl ON custkey=o_custkey;
The Optimizer does not use this join index to partially cover the following query because after
it rewrites the request, the query block that would use the compressed join index would need
to participate in an outer join operation, and Teradata Database does not support reading
compressed join index rows in outer join steps.
SELECT custkey, orderkey, linenumber, price
FROM cust
LEFT OUTER JOIN ordertbl ON custkey=o_custkey
LEFT OUTER JOIN lineitem ON orderkey=l_orderkey;
This restriction applies to any query block, including spooled subqueries and derived tables.
Restriction on Partial Coverage of Queries Containing a TOP n or TOP m
PERCENT Clause
A join index cannot be used to partially cover a query that specifies the TOP n or TOP m
PERCENT option.
SQL Reference: Data Definition Statements
387
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Restriction on Coverage by Join Indexes When a Join Index Definition
References More Tables Than a Query
Whether the Optimizer decides to include a join index in its query plan is a more complicated
choice than simply determining if the index contains all the table columns specified in the
query. The columns on which the base tables in the index definition are joined and their
respective referential constraints also play an important role. See “Rules for Whether Join
Indexes With Extra Tables Cover Queries” on page 391.
In many cases, the Optimizer does not consider using a join index in its access plan if that
index is defined on more tables than the query references. This is because the so-called extra
inner joins involving the tables not referenced by the query can cause both spurious row loss
and spurious duplicate row creation during the optimization process, and either outcome
produces incorrect results.
This outcome can be avoided, and the join index is more likely to be used in the query access
plan, if the extra inner joins are defined on primary key-foreign key relationships34 in the
underlying base tables that ensure proper row preservation.
In the case of join index outer joins, outer table rows are always preserved automatically, so
there is no requirement for a referential integrity constraint to exist in order to preserve them.
In the case of foreign key-primary key inner joins, the same preservation of rows follows from
a declarative referential integrity constraint. In this case, the Optimizer does consider a join
index with extra inner joins in its definition to cover a query. The following paragraphs
explain why a referential constraint preserves logical integrity.
Assume that the base tables in a join index definition can be divided into two distinct sets, s1
and s2.
s1 contains the base tables referenced in the query, while s2 contains the extra base tables the
query does not reference. The base tables in s1 are joined to the base tables in s2 on foreign
key-primary key columns, with the tables in s2 being the primary keys in the relationships.
The foreign key values cannot be null because if the foreign key column set contains nulls, the
losslessness of the foreign key table cannot be guaranteed.
The following assertions about these base tables are true:
•
The extra joins do not eliminate valid rows from the join result among the base tables in s1
because FOREIGN KEY and NOT NULL constraints ensure that every row in the foreign
key table finds its match in the primary key table.
•
The extra joins do not introduce duplicate rows in the join result among the base tables in
s1 because the primary key is, by definition, unique and not nullable.
These assertions are also true for extra joins made between base tables that are both in s2.
34. The referential integrity relationship between the base table primary and foreign keys can be specified
using any of the three available methods for establishing referential constraints between tables. See SQL
Reference: Data Definition Statements for further information.
388
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Therefore, the extra joins in a join index definition, if made on base tables that are defined in a
way that observes these assertions, preserve all the rows resulting from the joins among the
base tables in s1 and do not add spurious rows. This result permits the Optimizer to use the
join index to cover a query that references fewer tables than the index definition inner joins
together.
The Optimizer can select a join index for a query plan if the index contains either the same set,
or a subset, of the tables referenced by the query. If more tables are referenced in the join index
definition than are referenced by the query, the Optimizer generally does not consider that
index as a candidate for coverage because the extra joins can either eliminate rows or produce
duplicate rows or both.
Because a referential integrity relationship guarantees the losslessness of the foreign key table
in the join with its primary key table, extra tables in a join index definition do not disqualify it
from query plan consideration if the extra joins allow the join index to preserve all the rows
for the join result of the subset of tables in the query.
For example, suppose you define a join index on a set of 5 tables, t1 - t5, respectively, with
foreign key-primary key joins in the directions indicated (arrows point from a foreign key
table to its parent primary key table) by the following diagram:
t1 → t2 → t3 → t4 → t5
Queries that reference the following table subsets can be covered by this join index because the
extra joins, either between two tables where one is in the query and the other is not, or
between two tables that are both not in the query, do not cause any loss of rows for the join
result of the subset of tables in the query:
•
t1
•
t1, t2
•
t1, t2, t3
•
t1, t2, t3, t4
As a result of this property, the following conditions that reference extra joins can be exploited
by the Optimizer when the number of tables referenced by the join index definition exceeds
the number of tables referenced by the query. In each case, x1 is a unique RI-related column in
table t1 and x2 is a unique RI-related column in table t2:
SQL Reference: Data Definition Statements
389
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Join Index Extra Join
Condition
Qualifications
x1 = x2
• x1 is the foreign key in the relationship.
• t1 is referenced by the query.
• t2 is not referenced by the query.
x1 = x2
• x1 is the primary key in the relationship.
• t2 is referenced by the query.
• t1 is not referenced by the query.
x1 = x2
• x1 is the foreign key in the relationship.
• x2 is the primary key in the relationship.
• Neither t1 nor t2 is referenced by the query.
x1 = x2
• x1 is the primary key in the relationship.
• x2 is the foreign key in the relationship.
• Neither t1 nor t2 is referenced by the query.
One restriction with two critical exceptions must be added to the above optimization to make
the coverage safe: when one table referenced in the join index definition is the parent table of
more than one FK table, the join index is generally disqualified from covering any query that
references fewer tables than are referenced in the join index.
For example, suppose you define a join index on a set of 5 tables, t1 - t5, respectively, with
foreign key-primary key joins in the directions indicated (arrows point from a foreign key
table to its parent primary key table) by the following diagram:
t1 → t2 → t3 → t4 ← t5
For these RI relationships, table t4 is the parent table of both tables t3 and t5. The losslessness
of the foreign key table depends on the fact that the parent table has all the primary keys
available. Joining the parent table with another child table can render this premise false.
Therefore, the final join result cannot be viewed as lossless for any arbitrary subset of tables.
The following two points are exceptions to this restriction:
•
When the foreign key tables are joined on the foreign key columns, there is no loss on any
of the foreign key tables because they all reference the same primary key values in their
common parent table.
•
All foreign key tables reference the same primary key column in the primary key table. By
transitive closure, all these foreign key tables are related by equijoins on the foreign key
columns.
By specifying extra joins in the join index definition, you can greatly enhance its flexibility.
390
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
For example, suppose you have a star schema based on a sales fact table and the following
dimension tables:
•
customer
•
product
•
location
•
time
You decide it is desirable to define a join index that joins the fact table Sales to its various
dimension tables in order to avoid the relatively expensive join processing between the fact
table and its dimension tables whenever ad hoc join queries are made against them.
If there are foreign key-primary key relationships between the join columns, which is often the
case, the join index can also be used to optimize queries that only reference a subset of the
dimension tables.
Without taking advantage of this optimization, you must either create a different join index
for each category of query, incurring the greater cost of maintaining multiple join indexes, or
you lose the benefit of join indexes for optimizing the join queries on these tables altogether.
By exploiting the foreign key-primary key join properties, the same join index can be selected
by the Optimizer to generate access plans for a wide variety of queries.
Rules for Whether Join Indexes With Extra Tables Cover Queries
The following rules explain how to design a set of underlying base tables for a join index
definition in such a way to ensure that the Optimizer selects the index for an access plan if it
inner joins more tables than the query references:
IF there are more inner-joined tables in a join
index definition than the number of tables
referenced in a query and …
THEN the Optimizer …
the extra joins are not made on foreign keyprimary key columns in the underlying base
tables
does not consider the join index for the query plan.
the extra joins are made on foreign keyprimary key columns in the underlying base
tables
considers the join index for use in for the query plan.
This is because the presence of extra joins in the
definition can either eliminate existing rows from the
query evaluation or produce duplicate rows during
optimization.
both of the following conditions are true:
• The join column set of the inner table in
the extra outer join is unique
• Either the inner table or both the inner
and outer tables involved in the extra
outer join are extra tables
SQL Reference: Data Definition Statements
391
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
See the following topics for examples of properly defining join indexes to ensure that they can
cover queries that specify fewer tables than are specified in the join index:
•
“Examples That Obey the General Covering Rules for Extra Tables in the Join Index
Definition” on page 404
•
“Example 8: All Outer Joins in Join Index Definition” on page 406
•
“Example 9: All Inner Joins Without Aggregation in Join Index Definition” on page 406
•
“Example 10: All Inner Joins With Aggregation in Join Index Definition” on page 407
•
“Example 11: All Inner Joins With Aggregation in Join Index Definition” on page 408
•
“Example 12: More Inner Joined Tables in Aggregate Join Index Definition Than in
Query” on page 409
•
“Example 13: Join Index Left Outer Joined on Six Tables” on page 410
•
“Example 14: Many More Tables Referenced by Join Index Definition Than Referenced by
Query” on page 411
•
“Example 15: Using a Join Index That Has an Extra Inner Join In Its Definition” on
page 412
•
“Examples of Exceptions to the General Rules for Extra Tables in the Join Index
Definition” on page 413
•
“Example 16” on page 413
•
“Example 17” on page 414.
Maximum Number of Indexes Definable Per Data, Hash, or Join Index
Table
Up to 32 secondary,35 hash, and join indexes, in any combination, can be defined for one user
data base table.
Restriction on Number of Join Indexes Selected by the Optimizer Per Table
The Optimizer can use several join indexes for a single query, selecting one or more multitable
join indexes as well as additional single-table join indexes for its join plan. The join indexes
selected depend on the structure of the query, and the Optimizer might not choose all
applicable join indexes for the plan. Always examine your EXPLAIN reports to determine
which join indexes are used for the join plans generated for your queries. If a join index you
think should have been used by a query was not included in the join plan, try restructuring the
query and EXPLAIN it once again.
The join planning process selects a multitable join index to replace any individual table in a
query when the substitution further optimizes the query plan. For each such table replaced in
the join plan by a multitable join index, as many as two additional single-table join indexes
can also be considered as replacements if their inclusion reduces the size of the relation to be
processed, provides a better distribution, or offers additional covering.
35. Each multicolumn NUSI defined with an ORDER BY clause counts as two consecutive indexes in this
calculation (see “Why Consecutive Indexes Are Important For Value-Ordered NUSIs” on page 340).
392
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
The limit on the number of join indexes substituted per individual table in a query is enforced
to limit the number of possible combinations and permutations of table joins in the
Optimizer search space during its join planning phase. The rule helps to ensure that the
optimization is worth the effort: in other words, that the time spent generating the query plan
does not exceed the accrued performance enhancement.
Restrictions on Column Data Types
You cannot specify a column with a data type of either BLOB or CLOB in the definition of a
join index, nor for any other kind of index.
You cannot specify a column with a UDT type in the definition of a join index, nor for any
other kind of index.
Restrictions on Inequality Conditions in WHERE Clauses
The following rules apply to the use of inequality conditions in a join index WHERE clause:
•
Inequality conditions between columns from the same table are always valid.
•
Inequality conditions between columns from different tables are supported only if they are
ANDed to at least one equality condition.
•
Inequality conditions can be specified only for columns having the same data type in order
to enforce domain integrity.
•
The only valid comparison operators for an inequality condition are the following:
•
<
•
<=
•
>
•
>=
The following join index definition is valid because it obeys the first rule, making the WHERE
clause inequality on columns o_totalprice and o_unitprice, which are from the same table:
CREATE JOIN INDEX ord_price_idx AS
SELECT c_name, o_orderkey, o_orderdate
FROM orders, customer
WHERE o_totalprice <> o_unitprice;
The following join index definition is valid because it obeys the second rule, ANDing the
WHERE clause inequality on the o_totalprice and c_acctba columns, which are from different
tables, with the previously specified equality condition on o_custkey and c_custkey:
CREATE JOIN INDEX ord_cust_idx AS
SELECT c_name, o_orderkey, o_orderdate
FROM orders, customer
WHERE o_custkey = c_custkey
AND o_totalprice > c_acctbal;
Restrictions on Inequality Conditions in ON Clauses
Inequality conditions are not supported under any circumstances for ON clauses in join index
definitions.
SQL Reference: Data Definition Statements
393
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Restrictions and Limitations for Error Tables
You cannot create a join index on an error table (see “CREATE ERROR TABLE” on page 205).
Restrictions and Limitations for Load Utilities
You cannot use FastLoad, MultiLoad, or the Teradata Parallel Transporter operators LOAD
and UPDATE to load data into base tables that have join indexes because those indexes are not
maintained during the execution of these utilities. This is true both for NPPI join indexes and
for PPI join indexes. If you attempt to load data into base tables with join indexes using these
utilities, an error message returns and the load does not continue.
To load data into a join-indexed base table, you must drop all defined join indexes before you
can run FastLoad, MultiLoad, or the Teradata Parallel Transporter operators LOAD and
UPDATE.
Load utilities like TPump, BTEQ, and the Teradata Parallel Transporter operators INSERT
and STREAM, which perform standard SQL row inserts and updates, are supported for base
tables on which join indexes are defined.
Restrictions and Limitations for Archive and Restore
Though you can archive a database that contains join indexes, the Archive utility does not save
the join indexes themselves. This is true for both NPPI join indexes and for PPI join indexes.
Because no record of any join index that was defined in the database remains after a Restore
operation is performed, the SHOW JOIN INDEX and HELP DATABASE statements do not
indicate that the index ever existed.
The following table describes the behavior of the SHOW JOIN INDEX and HELP DATABASE
statements in this situation:
This SQL statement …
Reports the following information about join indexes after a partial database
restoration …
SHOW JOIN INDEX
a warning that the join index is not valid.
HELP DATABASE
the names of the pre-existing join indexes and no indication that they are
no longer valid.
After either a partial or full database restoration, you must drop any affected join index
definitions, recreate them, and collect new statistics for them.
Restrictions and Limitations for Ordered Analytical Functions
When an ordered analytical function is specified on columns that are also defined for a
compressed join index, the Optimizer does not select the join index to process the query.
Restrictions and Limitations for UDTs
Join indexes cannot contain UDT columns.
394
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Restrictions and Limitations for Large Objects
Join indexes cannot contain BLOB or CLOB columns.
Restrictions and Limitations for System-Derived PARTITION Columns
Join indexes cannot contain system-derived PARTITION or PARTITION#Ln columns, where
n ranges from 1 - 15, inclusive, in their definition.
A join index can contain a user-defined column named PARTITION or PARTITION#Ln in its
definition.
Restrictions and Limitations for the Reconfig Utility
You must drop and rebuild all value-ordered join indexes after you run the Reconfig utility
(see Utilities).
The same is not true for hash-ordered join indexes.
Restrictions on Creating a Join Index on a Table Concurrent With Random
AMP Sample Emulation on That Table
You cannot create a join index for a table while that table is subject to random AMP sample
emulation. If you attempt to do so, the system returns an error.
To disable random AMP sampling, use the DIAGNOSTIC HELP SAMPLES statement (see
“DIAGNOSTIC HELP SAMPLES” on page 1402) to determine which samples have been set,
then use the DIAGNOSTIC SET SAMPLES statement (see “DIAGNOSTIC SET SAMPLES”
on page 1404) to disable them.
If you want to use random AMP sampling on the table with a new join index, you must use
the following general procedure:
1
Create the new join index on the table on the target system.
2
Extract a fresh random AMP sample from the target system.
3
Apply the fresh sample to the source system.
4
End of procedure.
Permanent Journal Recovery of Join Indexes Is Not Supported
You can use ROLLBACK or ROLLFORWARD statements to recover base tables that have join
indexes defined on them; however, the join indexes are not rebuilt during the recovery process.
Instead, they are marked as not valid. You must drop and recreate any such join indexes before
the Optimizer can use them again to generate a query plan.
When a join index has been marked not valid, the SHOW JOIN INDEX statement displays a
special status message to inform you that the join index has been so marked.
SQL Reference: Data Definition Statements
395
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 1: Creating and Using a Simple Join Index
This example set uses the following table definitions:
CREATE TABLE customer (
c_custkey
INTEGER,
c_name
CHARACTER(26),
c_address
VARCHAR(41),
c_nationkey INTEGER,
c_phone
CHARACTER(16),
c_acctbal
DECIMAL(13,2),
c_mktsegment CHARACTER(21),
c_comment
VARCHAR(127))
UNIQUE PRIMARY INDEX (c_custkey);
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1),
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_commment
VARCHAR(79))
UNIQUE PRIMARY INDEX (o_orderkey);
CREATE TABLE lineitem (
l_orderkey
INTEGER NOT NULL,
l_partkey
INTEGER NOT NULL,
l_suppkey
INTEGER,
l_linenumber
INTEGER,
l_quantity
INTEGER NOT NULL,
l_extendedprice DECIMAL(13,2) NOT NULL,
l_discount
DECIMAL(13,2),
l_tax
DECIMAL(13,2),
l_returnflag
CHARACTER(1),
l_linestatus
CHARACTER(1),
l_shipdate
DATE FORMAT 'yyyy-mm-dd',
l_commitdate
DATE FORMAT 'yyyy-mm-dd',
l_receiptdate
DATE FORMAT 'yyyy-mm-dd',
l_shipinstruct VARCHAR(25),
l_shipmode
VARCHAR(10),
l_comment
VARCHAR(44))
PRIMARY INDEX (l_orderkey);
The following request defines a join index on these tables. Subsequent examples demonstrate
the effect of this join index on how the Optimizer processes various queries.
CREATE JOIN INDEX order_join_line AS
SELECT (l_orderkey, o_orderdate, o_custkey, o_totalprice),
(l_partkey, l_quantity, l_extendedprice, l_shipdate)
FROM lineitem
LEFT JOIN orders ON l_orderkey = o_orderkey
ORDER BY o_orderdate
PRIMARY INDEX (l_orderkey);
*** Index has been created.
*** Total elapsed time was 15 seconds.
396
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
The following EXPLAIN report shows how the newly created join index, order_join_line,
might be used by the Optimizer:
EXPLAIN SELECT o_orderdate, o_custkey, l_partkey, l_quantity,
l_extendedprice
FROM lineitem, orders
WHERE l_orderkey = o_orderkey;
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.order_join_line.
2) Next, we lock LOUISB.order_join_line for read.
3) We do an all-AMPs RETRIEVE step from join index table
LOUISB.order_join_line by way of an all-rows scan with a condition
of ("NOT (LOUISB.order_join_line.o_orderdate IS NULL)") into Spool 1,
which is built locally on the AMPs. The input table will not be
cached in memory, but it is eligible for synchronized scanning.
The result spool file will not be cached in memory. The size of
Spool 1 is estimated to be 1,000,000 rows. The estimated time for
this step is 4 minutes and 27 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
The following EXPLAIN report shows how the join index might be used in a query when an
additional search condition is added on the join indexed rows:
EXPLAIN SELECT o_orderdate, o_custkey, l_partkey, l_quantity,
l_extendedprice
FROM lineitem, orders
WHERE l_orderkey = o_orderkey
AND o_orderdate > '1997-11-01';
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.order_join_line.
2) Next, we lock LOUISB.order_join_line for read.
3) We do an all-AMPs RETRIEVE step from join index table
LOUISB.order_join_line with a range constraint of (
"LOUISB.order_join_line.Field_1026 > 971101") with a residual
condition of ("(NOT (LOUISB.order_join_line.o_orderdate IS NULL ))
AND (LOUISB.order_join_line.Field_1026 > 971101)") into Spool 1,
which is built locally on the AMPs. The input table will not be
cached in memory, but it is eligible for synchronized scanning.
The size of Spool 1 is estimated to be 1000 rows. The estimated time
for this step is 0.32 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
The following EXPLAIN report shows how the join index might be used in a query when
aggregation is performed on the join indexed rows:
EXPLAIN SELECT l_partkey, avg(l_quantity), AVG(l_extendedprice)
FROM lineitem, orders
WHERE l_orderkey = o_orderkey
AND o_orderdate > '1997-11-01'
GROUP BY l_partkey;
SQL Reference: Data Definition Statements
397
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
RowHash to prevent global deadlock for LOUISB.order_join_line.
2) Next, we lock LOUISB.order_join_line for read.
3) We do a SUM step to aggregate from join index table
LOUISB.order_join_line with a range constraint of (
"LOUISB.order_join_line.Field_1026 > 971101") with a residual
condition of ("(LOUISB.order_join_line.Field_1026 > 971101) AND (NOT
(LOUISB.order_join_line.o_orderdate IS NULL ))"), and the grouping
identifier in field 1. Aggregate Intermediate Results are
computed globally, then placed in Spool 3. The input table will
not be cached in memory, but it is eligible for synchronized
scanning.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1, which is built locally on the AMPs.
The size of Spool 1 is estimated to be 10 rows. The estimated time
for this step is 0.32 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
The following EXPLAIN report shows how the join index might be used in a query when join
indexed rows are used to join with another base table:
EXPLAIN SELECT o_orderdate, c_name, c_phone, l_partkey, l_quantity,
l_extendedprice
FROM lineitem, orders, customer
WHERE l_orderkey = o_orderkey
AND o_custkey = c_custkey;
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.order_join_line.
2) Next, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.customer.
3) We lock LOUISB.order_join_line for read, and we lock LOUISB.customer
for read.
4) We do an all-AMPs RETRIEVE step from join index table
LOUISB.order_join_line by way of an all-rows scan with a condition
of ("NOT (LOUISB.order_join_line.o_orderdate IS NULL)") into Spool 2,
which is redistributed by hash code to all AMPs. Then we do a
SORT to order Spool 2 by row hash. The size of Spool 2 is
estimated to be 1,000,000 rows. The estimated time for this step
is 1 minute and 53 seconds.
5) We do an all-AMPs JOIN step from LOUISB.customer by way of a
Row Hash match scan with no residual conditions, which is joined to
Spool 2 (Last Use). LOUISB.customer and Spool 2 are joined using
a merge join, with a join condition of ("Spool_2.o_custkey =
LOUISB.customer.c_custkey"). The result goes into Spool 1, which
is built locally on the AMPs. The size of Spool 1 is estimated to
be 1,000,000 rows. The estimated time for this step is 32.14
seconds.
6) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
The following EXPLAIN report shows how the join index might be used in a query of a single
table:
EXPLAIN SELECT l_orderkey, l_partkey, l_quantity, l_extendedprice
FROM lineitem
WHERE l_partkey = 1001;
398
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.order_join_line.
2) Next, we lock LOUISB.order_join_line for read.
3) We do an all-AMPs RETRIEVE step from join index table
LOUISB.order_join_line by way of an all-rows scan with a condition
of ("LOUISB.order_join_line.l_partkey = 1001") into Spool 1, which
is built locally on the AMPs. The input table will not be cached
in memory, but it is eligible for synchronized scanning. The
result spool file will not be cached in memory. The size of Spool
1 is estimated to be 100 rows. The estimated time for this step
is 59.60 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
Example 2: Specifying a Disk I/O Checksum Value for a Join Index
The following example defines a join index with a disk I/O checksum value of MEDIUM. If
secondary indexes are defined on ord_cust_idx, then the specified checksum value applies to
them as well.
CREATE JOIN INDEX ord_cust_idx, CHECKSUM = MEDIUM AS
SELECT c_nationkey, SUM(o_totalprice(FLOAT)) AS price, o_orderdate
FROM orders, customer
WHERE o_custkey = c_custkey
GROUP BY c_nationkey, o_orderdate;
ORDER BY o_orderdate;
Example 3: Defining and Using a Simple Join Index With an n-way Join
Result
The following example shows the creation of a join index defined with a multiway join result
and then shows how the Optimizer uses the join index to process a query on the base tables for
which it is defined:
CREATE JOIN INDEX cust_order_join_line AS
SELECT (l_orderkey, o_orderdate, c_nationkey, o_totalprice),
(l_partkey, l_quantity, l_extendedprice, l_shipdate)
FROM (lineitem
LEFT JOIN orders ON l_orderkey = o_orderkey)
INNER JOIN customer ON o_custkey = c_custkey
PRIMARY INDEX (l_orderkey);
*** Index has been created.
*** Total elapsed time was 20 seconds.
EXPLAIN SELECT l_orderkey, o_orderdate, o_totalprice,
l_partkey, l_quantity, l_extendedprice, l_shipdate
FROM lineitem, orders, customer
WHERE l_orderkey = o_orderkey
AND o_custkey = c_custkey
AND c_nationkey = 10;
*** Help information returned. 16 rows.
*** Total elapsed time was 1 second.
SQL Reference: Data Definition Statements
399
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Explanation
-------------------------------------------------------------------------1) First, we lock a distinct LOUISB."pseudo table" for read on a
Row Hash to prevent global deadlock for LOUISB.cust_order_join_line.
2) Next, we lock LOUISB.cust_order_join_line for read.
3) We do an all-AMPs RETRIEVE step from join index table
LOUISB.cust_order_join_line by way of an all-rows scan with a
condition of ("LOUISB.cust_order_join_line.c_nationkey = 10") into
Spool 1, which is built locally on the AMPs. The input table will
not be cached in memory, but it is eligible for synchronized
scanning. The result spool file will not be cached in memory.
The size of Spool 1 is estimated to be 200 rows. The estimated time
for this step is 3 minutes and 57 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
Example 4: Using the EXTRACT Function With a Join Index Definition
Join index definitions support the EXTRACT function.
The following example illustrates the use of the EXTRACT function in the definition of an
aggregate join index:
CREATE JOIN INDEX ord_cust_idx_2 AS
SELECT c_nationkey, SUM(o_totalprice(FLOAT)) AS price,
EXTRACT(YEAR from o_orderdate) AS o_year
FROM orders, customer
WHERE o_custkey = c_custkey
GROUP BY c_nationkey, o_year
ORDER BY o_year;
The aggregation is based only on the year of o_orderdate, which has fewer groups than the
entire o_orderdate, so ord_cust_idx_2 is much smaller than ord_cust_idx.
On the other hand, the use for ord_cust_idx_2 is more limited than ord_custidx. In particular,
ord_cust_idx_2 can only be used to satisfy queries that select full years of orders.
For example, ord_cust_idx_2 cannot be used for the query analyzed in “Example 5: Creating
and Using an Aggregate Join Index” on page 401, but the following query does profit from its
use:
SELECT COUNT(*), SUM(o_totalprice)
FROM orders, customer
WHERE o_custkey = c_custkey
AND
o_orderdate > DATE ‘1998-01-01’
AND
o_orderdate < DATE ‘1998-12-31’
GROUP BY c_nationkey;
400
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 5: Creating and Using an Aggregate Join Index
This example set uses the following table definitions:
CREATE TABLE customer (
c_custkey
INTEGER NOT NULL,
c_name
CHARACTER(26) CASESPECIFIC NOT NULL,
c_address
VARCHAR(41),
c_nationkey INTEGER,
c_phone
CHARACTER(16),
c_acctbal
DECIMAL(13,2),
c_mktsegment CHARACTER(21),
c_comment
VARCHAR(127))
UNIQUE PRIMARY INDEX (c_custkey);
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'YYYY-MM-DD' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
UNIQUE PRIMARY INDEX (o_orderkey);
Consider the following aggregate join query:
SELECT COUNT(*), SUM(o_totalprice)
FROM orders, customer
WHERE o_custkey = c_custkey
AND
o_orderdate > DATE ‘1998-09-20’
AND
o_orderdate < DATE ‘1998-10-15’
GROUP BY c_nationkey;
Without an aggregate join index, a typical execution plan for this query might involve the
following stages:
1
Redistribute orders into a spool file.
2
Sort the spool file on o_custkey.
3
Merge join the sorted spool file and the customer file.
4
Aggregate the result of the merge join.
5
End of process.
Suppose you define the following aggregate join index, which aggregates o_totalprice over a
join of orders and customer:
SELECT c_nationkey, SUM(o_totalprice(FLOAT)) AS price, o_orderdate
FROM orders, customer
WHERE o_custkey = c_custkey
GROUP BY c_nationkey, o_orderdate
ORDER BY o_orderdate;
The execution plan produced by the Optimizer for this query includes an aggregate step on
the aggregate join index, which is much smaller than either one of the join tables. You can
confirm this by performing an EXPLAIN on the query.
SQL Reference: Data Definition Statements
401
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
EXPLAIN SELECT COUNT(*), SUM(o_totalprice)
FROM orders, customer
WHERE o_custkey = c_custkey
AND
o_orderdate > DATE ‘1998-09-20’
AND
o_orderdate < DATE ‘1998-10-15’
GROUP BY c_nationkey;
*** Help information returned. 18 rows.
*** Total elapsed time was 3 seconds.
Explanation
------------------------------------------------------------1) First, we lock a distinct TPCD."pseudo table" for read on a
RowHash to prevent global deadlock for TPCD.ord_cust_idx.
2) Next, we lock TPCD.ord_cust_idx for read.
3) We do a SUM step to aggregate from join index table
TPCD.ordcustidx by way of an all-rows scan with a condition of (
"(TPCD.ord_cust_idx.O_ORDERDATE > DATE '1998-09-20') AND
(TPCD.ord_cust_idx.O_ORDERDATE < DATE '1998-10-15')"), and the
grouping identifier in field 1. Aggregate Intermediate Results
are computed globally, then placed in Spool 2. The size of Spool
2 is estimated to be 1 row.
4) We do an all-AMPs RETRIEVE step from Spool 2 (Last Use) by way of
an all-rows scan into Spool 1, which is built locally on the AMPs.
The size of Spool 1 is estimated with no confidence to be 1 row.
The estimated time for this step is 0.17 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
Example 6: Join Index With a Single-Level Partitioned Primary Index
Assume the following base table definition:
CREATE TABLE orders (
o_orderkey
INTEGER NOT NULL,
o_custkey
INTEGER,
o_orderstatus
CHARACTER(1) CASESPECIFIC,
o_totalprice
DECIMAL(13,2) NOT NULL,
o_orderdate
DATE FORMAT 'yyyy-mm-dd' NOT NULL,
o_orderpriority CHARACTER(21),
o_clerk
CHARACTER(16),
o_shippriority INTEGER,
o_comment
VARCHAR(79))
UNIQUE PRIMARY INDEX (o_orderkey, o_orderdate);
The following DDL creates a single-level PPI join index on the base table named orders:
CREATE JOIN INDEX ordJI1 AS
SELECT o_custkey, o_totalprice
FROM orders
PRIMARY INDEX (o_custkey)
PARTITION BY RANGE_N(CAST(o_totalprice AS INTEGER)
BETWEEN 0
AND 999999
EACH
100, NO RANGE);
402
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 7: Another SLPPI Join Index
The following example shows how a noncompressed PPI join index can help query
performance.
Assume a star schema with the following fact and dimension tables defined in the physical
data model:
•
A fact table named sales with columns sale_date, store_id, prod_id, and amount.
•
The following three dimension tables:
•
calendar, with columns dayofmth, mth, and yr and a primary index defined on yr and
mth.
•
product, with columns prod_id and prod_category.
•
org, with columns store_id, area, division, and business_unit.
You might want to create an aggregate join index with daily summary data like the following
join index named sales_summary to answer a set of ad hoc queries:
CREATE JOIN INDEX sales_summary AS
SELECT sale_date, prod_category, division,
SUM(amount) AS daily_sales
FROM calendar AS c, product AS p, org AS o, sales AS s
WHERE c.dayofmth = s.sale_date
AND
p.prod_id = s.prod_id
AND
o.store_id = s.store_id
AND
s.sale_date BETWEEN DATE '1991-01-01' AND DATE '2006-12-31'
GROUP BY sale_date, prod_category, division
PRIMARY INDEX(sale_date, prod_category, division)
PARTITION BY RANGE_N(sale_date BETWEEN DATE '1991-01-01'
AND
DATE '2006-12-31'
EACH INTERVAL '1' MONTH);
A wide range of queries can make use of this join index, especially when there are foreign
key-primary key relationships defined between the fact table and the dimension tables that
enable the join index to be used as a broad join index to cover queries over a subset of
dimension tables.
Significant performance gains can be achieved with this join index when the Optimizer uses it
to answer the queries that have equality or range constraints on the sale_date column. The
system applies optimizations such as Static Partition Elimination and Rowkey-Based Merge
Join to a PPI join index in the same way it does to a PPI base table.
For example, the following query needs to access only 12 of the 192 total partitions, which
saves as much as 93.75 percent on disk reads, and proportional savings on elapsed time
compared with an otherwise identical NPPI join index, which requires a full-table scan.
SELECT prod_category, SUM(amount) AS daily_sales
FROM calendar c, product p, sales s
WHERE c.dayofmth = s.sale_date
AND
p.prod_id = s.prod_id
AND
sale_date BETWEEN DATE '2006-01-01' AND DATE '2006-12-31'
GROUP BY prod_category;
SQL Reference: Data Definition Statements
403
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
While a join index often significantly improves query response times, you must also consider
the overhead of maintaining the index when inserts, deletes, updates, and merges occur to the
base table on which it is defined.
A noncompressed PPI join index might see significant improvement in maintenance
performance because of PPI-related optimizations. For example, partitioning on the DATE
column in the join index also helps insert performance if the transaction data are inserted into
the sales table according to a time sequence.
The Teradata Parallel Transporter UPDATE operator, MultiLoad, and FastLoad cannot be
used to load rows into base tables with join indexes. Because of this limitation, you must use
either of the following workarounds:
•
Use the Teradata Parallel Data Pump utility to load the rows into sales
•
FastLoad the rows into a staging table and then use either an INSERT … SELECT or
MERGE request with error logging to load the rows into sales.
Because the inserted rows are clustered in the data blocks corresponding to the appropriate
partitions, the number of data blocks the system must read and write is reduced compared to
an NPPI join index, where the inserted rows scatter among all the data blocks.
On the other hand, it is possible that the maintenance of a PPI join index makes the index less
efficient than it would be with an NPPI. For example, if the primary index of the join index
does not include the partitioning columns, and a DELETE or UPDATE statement specifies a
constraint on the primary index, the system must probe all partitions on the AMP to maintain
the SLPPI join index as opposed to the fast primary index access for the join index when
defined with an NPPI.
Examples That Obey the General Covering Rules for Extra Tables in the
Join Index Definition
The following set of base tables, join indexes, queries, and EXPLAIN reports demonstrate how
the referential integrity relationships among the underlying base tables in a join index
definition influence whether the Optimizer selects the index for queries that reference fewer
base tables than are referenced by the join index:
404
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
CREATE SET TABLE t1, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
x1 INTEGER NOT NULL,
a1 INTEGER NOT NULL,
b1 INTEGER NOT NULL,
c1 INTEGER NOT NULL,
d1 INTEGER NOT NULL,
e1 INTEGER NOT NULL,
f1 INTEGER NOT NULL,
g1 INTEGER NOT NULL,
h1 INTEGER NOT NULL,
i1 INTEGER NOT NULL,
j1 INTEGER NOT NULL,
k1 INTEGER NOT NULL,
CONSTRAINT ri1 FOREIGN KEY (a1, b1, c1) REFERENCES t2 (a2, b2, c2),
CONSTRAINT ri2 FOREIGN KEY (d1) REFERENCES t3(d3),
CONSTRAINT ri3 FOREIGN KEY (e1, f1) REFERENCES t4 (e4, f4),
CONSTRAINT ri4 FOREIGN KEY (g1, h1, i1, j1)
REFERENCES t5(g5, h5, i5, j5),
CONSTRAINT ri5 FOREIGN KEY (k1) REFERENCES t6(k6));
CREATE SET TABLE t2, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
a2 INTEGER NOT NULL,
b2 INTEGER NOT NULL,
c2 INTEGER NOT NULL,
x2 INTEGER)
UNIQUE PRIMARY INDEX(a2, b2, c2);
CREATE SET TABLE t3, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
d3 INTEGER NOT NULL,
x3 INTEGER)
UNIQUE PRIMARY INDEX(d3);
CREATE SET TABLE t4, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
e4 INTEGER NOT NULL,
f4 INTEGER NOT NULL,
x4 INTEGER)
UNIQUE PRIMARY INDEX(e4, f4);
CREATE SET TABLE t5, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
g5 INTEGER NOT NULL,
h5 INTEGER NOT NULL,
i5 INTEGER NOT NULL,
j5 INTEGER NOT NULL,
x5 INTEGER)
UNIQUE PRIMARY INDEX(g5, h5, i5, j5);
CREATE SET TABLE t6, NO FALLBACK, NO BEFORE JOURNAL,
NO AFTER JOURNAL (
k6 INTEGER NOT NULL,
x6 INTEGER)
UNIQUE PRIMARY INDEX(k6);
SQL Reference: Data Definition Statements
405
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 8: All Outer Joins in Join Index Definition
The following join index definition left outer joins t1 to t3 on da=d3 and then left outer joins
that result to t6 on k1=k6:
CREATE JOIN INDEX jiout AS
SELECT d1, d3, k1, k6, x1
FROM t1 LEFT OUTER JOIN t3 ON d1=d3
LEFT OUTER JOIN t6 ON k1=k6;
You would expect the Optimizer to use jiout with the following query, because all the outer
joins in the join index are inner joined to the query tables on unique columns (d1 and k1 are
declared foreign keys in t1 and d3 and k6, the primary keys for t3 and t6, respectively, are
declared as the unique primary index for those tables).
The bold EXPLAIN report text indicates that the Optimizer does use jiout in its query plan.
EXPLAIN SELECT d1, SUM(x1)
FROM t1, t3
WHERE d1=d3
GROUP by 1;
*** Help information returned. 17 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.jiout.
2) Next, we lock HONG_JI.jiout for read.
3) We do an all-AMPs SUM step to aggregate from HONG_JI.jiout by way
of an all-rows scan with no residual conditions, and the grouping
identifier in field 1. Aggregate Intermediate Results are
computed locally, then placed in Spool 3. The size of Spool 3 is
estimated with low confidence to be 1 row. The estimated time for
this step is 0.03 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with low confidence
to be 1 row. The estimated time for this step is 0.04 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
Example 9: All Inner Joins Without Aggregation in Join Index Definition
The following simple join index definition specifies inner joins on tables t1, t3 and t6:
CREATE JOIN INDEX jiin AS
SELECT d1, d3, k1, k6, x1
FROM t1, t3, t6
WHERE d1=d3
AND k1=k6;
You would expect the Optimizer to use jiin with the following query, and the bold EXPLAIN
report text indicates that it does.
EXPLAIN SELECT d1, SUM(x1)
FROM t1, t3
WHERE d1=d3
GROUP BY 1;
406
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.jiin.
2) Next, we lock HONG_JI.jiin for read.
3) We do an all-AMPs SUM step to aggregate from HONG_JI.jiin by way
of an all-rows scan with no residual conditions, and the grouping
identifier in field 1. Aggregate Intermediate Results are
computed locally, then placed in Spool 3. The size of Spool 3 is
estimated with low confidence to be 1 row. The estimated time for
this step is 0.03 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with low confidence
to be 1 row. The estimated time for this step is 0.04 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
Example 10: All Inner Joins With Aggregation in Join Index Definition
The following aggregate join index definition specifies inner joins on tables t1, t2, and t4:
CREATE JOIN INDEX jiin_aggr AS
SELECT a1, e1, SUM(x1) AS total
FROM t1, t2, t4
WHERE a1=a2
AND
e1=e4
AND
a1>1
GROUP BY 1, 2;
You would expect the Optimizer to use join index jiin_aggr in its plan for the following query
because it has the same join term as the query.
The bold EXPLAIN report text indicates that the Optimizer does use jiin_aggr in its plan:
EXPLAIN SELECT a1, e1, SUM(x1) AS total
FROM t1, t2, t4
WHERE a1=a2
AND
e1=e4
AND
a1>2
GROUP BY 1, 2;
*** Help information returned. 13 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.jiin_aggr.
2) Next, we lock HONG_JI.jiin_aggr for read.
3) We do an all-AMPs RETRIEVE step from HONG_JI.jiin_aggr by way of
an all-rows scan with a condition of ("(HONG_JI.jiin_aggr.a1 > 2)
AND (HONG_JI.jiin_aggr.a1 >= 3)") into Spool 1 (group_amps), which
is built locally on the AMPs. The size of Spool 1 is estimated
with no confidence to be 1 row. The estimated time for this step
is 0.03 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.03 seconds.
SQL Reference: Data Definition Statements
407
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 11: All Inner Joins With Aggregation in Join Index Definition
You would not expect the Optimizer to use join index jiin_aggr (see “Example 10: All Inner
Joins With Aggregation in Join Index Definition” on page 407) in its plan for the following
query because the conditions b1=b2 and f1=f4 are not covered by the join index defined by
jiin_aggr. As a result, the Optimizer specifies a full-table scan to retrieve the specified rows.
The EXPLAIN report text indicates that the Optimizer does not choose jiin_aggr to cover the
query:
EXPLAIN SELECT a1, e1, SUM(x1) AS total
FROM t1, t2, t4
WHERE b1=b2
AND
f1=f4
AND
a1>2
GROUP BY 1, 2;
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.t4.
2) Next, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.t2.
3) We lock a distinct HONG_JI."pseudo table" for read on a RowHash to
prevent global deadlock for HONG_JI.t1.
4) We lock HONG_JI.t4 for read, we lock HONG_JI.t2 for read, and we
lock HONG_JI.t1 for read.
5) We do an all-AMPs RETRIEVE step from HONG_JI.t1 by way of an
all-rows scan with a condition of ("HONG_JI.t1.a1 > 2") into Spool
4 (all_amps), which is duplicated on all AMPs. The size of Spool
4 is estimated with no confidence to be 2 rows. The estimated
time for this step is 0.03 seconds.
6) We do an all-AMPs JOIN step from HONG_JI.t2 by way of an all-rows
scan with no residual conditions, which is joined to Spool 4 (Last
Use). HONG_JI.t2 and Spool 4 are joined using a product join,
with a join condition of ("b1 = HONG_JI.t2.b2"). The result goes
into Spool 5 (all_amps), which is duplicated on all AMPs. The
size of Spool 5 is estimated with no confidence to be 3 rows. The
estimated time for this step is 0.04 seconds.
7) We do an all-AMPs JOIN step from HONG_JI.t4 by way of an all-rows
scan with no residual conditions, which is joined to Spool 5 (Last
Use). HONG_JI.t4 and Spool 5 are joined using a product join,
with a join condition of ("f1 = HONG_JI.t4.f4"). The result goes
into Spool 3 (all_amps), which is built locally on the AMPs. The
size of Spool 3 is estimated with no confidence to be 2 rows. The
estimated time for this step is 0.04 seconds.
8) We do an all-AMPs SUM step to aggregate from Spool 3 (Last Use) by
way of an all-rows scan, and the grouping identifier in field 1.
Aggregate Intermediate Results are computed globally, then placed
in Spool 6. The size of Spool 6 is estimated with no confidence
to be 2 rows. The estimated time for this step is 0.05 seconds.
9) We do an all-AMPs RETRIEVE step from Spool 6 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with no confidence
to be 2 rows. The estimated time for this step is 0.04 seconds.
10) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
408
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 12: More Inner Joined Tables in Aggregate Join Index Definition
Than in Query
The following aggregate join index definition specifies inner joins on tables t1, t3, and t6 using
conditions that exploit a foreign key-primary key relationship between table t1 and tables t3
and t6, respectively:
CREATE JOIN INDEX jiin_aggr AS
SELECT d1, k1, SUM(x1) AS total
FROM t1, t3, t6
WHERE d1=d3
AND
k1=k6
GROUP BY 1, 2;
You would expect the Optimizer to include join index jiin_aggr in its access plan for the
following query even though jiin_aggr is defined with an inner joined table, t6, that the query
does not reference. This is acceptable to the Optimizer because of the foreign key-primary key
relationship between t1 and the extra table, t6, on columns k1 and k6,which have a foreign
key-primary key relationship and are explicitly defined as a foreign key and as the unique
primary index for their respective tables.
The bold EXPLAIN report text indicates that the Optimizer does select jiin_aggr for the query
plan:
EXPLAIN SELECT d1, SUM(x1)
FROM t1, t3
WHERE d1=d3
GROUP BY 1;
*** Help information returned. 17 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.jiin_aggr.
2) Next, we lock HONG_JI.jiin_aggr for read.
3) We do an all-AMPs SUM step to aggregate from HONG_JI.jiin_aggr by
way of an all-rows scan with no residual conditions, and the
grouping identifier in field 1. Aggregate Intermediate Results
are computed locally, then placed in Spool 3. The size of Spool 3
is estimated with low confidence to be 1 row. The estimated time
for this step is 0.03 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with low confidence
to be 1 row. The estimated time for this step is 0.04 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
SQL Reference: Data Definition Statements
409
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 13: Join Index Left Outer Joined on Six Tables
The following join index definition left outer joins table t1 with, in succession, tables t2, t3, t4,
t5, and t6 on a series of equality conditions made on foreign key-primary key relationships
among the underlying base tables:
CREATE JOIN INDEX jiout AS
SELECT a1, b1, c1, c2, d1, d3, e1, e4, f1, g1, h1, i1, j1, j5, k1,
k6, x1
FROM t1
LEFT OUTER JOIN t2 ON a1=a2
AND b1=b2
AND c1=c2
LEFT OUTER JOIN t3 ON d1=d3
LEFT OUTER JOIN t4 ON e1=e4
AND f1=f4
LEFT OUTER JOIN t5 ON g1=g5
AND h1=h5
AND i1=i5
AND j1=j5
LEFT OUTER JOIN t6 ON k1=k6;
Even though the following query references fewer tables than are defined in the join index, you
would expect the Optimizer to include join index ji_out in its access plan because all the extra
outer joins are defined on unique columns and the extra tables are the inner tables in the outer
joins.
The bold EXPLAIN report text indicates that the Optimizer does select ji_out for the query
plan:
EXPLAIN SELECT a1, b1, c1, SUM(x1)
FROM t1, t2
WHERE a1=a2
AND
b1=b2
AND
c1=c2
GROUP BY 1, 2, 3;
*** Help information returned. 18 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.jiout.
2) Next, we lock HONG_JI.jiout for read.
3) We do an all-AMPs SUM step to aggregate from HONG_JI.jiout by way
of an all-rows scan with no residual conditions, and the grouping
identifier in field 1. Aggregate Intermediate Results are
computed locally, then placed in Spool 3. The size of Spool 3 is
estimated with high confidence to be 2 rows. The estimated time
for this step is 0.03 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with high
confidence to be 2 rows. The estimated time for this step is 0.04
seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
410
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 14: Many More Tables Referenced by Join Index Definition Than
Referenced by Query
The following join index definition specifies all inner joins on tables t1, t2, t3, t4,t5 and t6 and
specifies equality conditions on all the foreign key-primary key relationships among those
tables:
CREATE JOIN INDEX ji_in AS
SELECT a1, b1, c1, c2, d1, d3, e1, e4, f1, g1, g5, h1, i1, j1, k1,
k6, x1
FROM t1, t2, t3, t4, t5, t6
WHERE a1=a2
AND
b1=b2
AND
c1=c2
AND
d1=d3
AND
e1=e4
AND
f1=f4
AND
g1=g5
AND
h1=h5
AND
i1=i5
AND
j1=j5
AND
k1=k6;
Even though 6 tables are referenced in the join index definition, and all its join conditions are
inner joins, you would expect the Optimizer to include join index ji_in in its query plan for
the following query, which only references 2 of the 6 tables, because all the conditions in the
join index definition are based on foreign key-primary key relationships among the
underlying base tables.
The bold EXPLAIN report text indicates that the Optimizer does select ji_in for the query
plan:
EXPLAIN SELECT a1, b1, c1, SUM(x1)
FROM t1, t2
WHERE a1=a2
AND
b1=b2
AND
c1=c2
GROUP BY 1, 2, 3;
*** Help information returned. 18 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for read on a
RowHash to prevent global deadlock for HONG_JI.ji_in.
2) Next, we lock HONG_JI.ji_in for read.
3) We do an all-AMPs SUM step to aggregate from HONG_JI.ji_in by way
of an all-rows scan with no residual conditions, and the grouping
identifier in field 1. Aggregate Intermediate Results are
computed locally, then placed in Spool 3. The size of Spool 3 is
estimated with high confidence to be 2 rows. The estimated time
for this step is 0.03 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with high
confidence to be 2 rows. The estimated time for this step is 0.04
seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
SQL Reference: Data Definition Statements
411
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
Example 15: Using a Join Index That Has an Extra Inner Join In Its
Definition
The following example illustrates how the Optimizer uses a join index with an extra inner join
when the connections among the tables in its definition are appropriately defined.
Suppose you have the following table definitions:
CREATE SET TABLE fact (
f_d1 INTEGER NOT NULL,
f_d2 INTEGER NOT NULL,
FOREIGN KEY (f_d1) REFERENCES WITH NO CHECK OPTION dim1 (d1),
FOREIGN KEY (f_d2) REFERENCES WITH NO CHECK OPTION dim2 (d2))
UNIQUE PRIMARY INDEX (f_d1,f_d2);
CREATE SET TABLE dim1 (
a1 INTEGER NOT NULL,
d1 INTEGER NOT NULL,
FOREIGN KEY (a1) REFERENCES WITH NO CHECK OPTION dim1_1 (d11))
UNIQUE PRIMARY INDEX (d1);
CREATE SET TABLE dim2 (
d1 INTEGER NOT NULL,
d2 INTEGER NOT NULL)
UNIQUE PRIMARY INDEX (d2);
CREATE SET TABLE dim1_1 (
d11 INTEGER NOT NULL,
d22 INTEGER NOT NULL)
UNIQUE PRIMARY INDEX (d11);
In the following join index definition, the fact table is joined with dimension tables dim1 and
dim2 by foreign key-primary key joins on fact.f_d1=dim1.d1 and fact.f_d2=dim2.d2.
Dimension table dim1 is also joined with its dimension subtable dim1_1 by a foreign
key-primary key join on dim1.a1=dim1_1.d11. A query on the fact and dim2 tables uses the
join index ji_all because of its use of foreign key-primary key relationships among the tables:
CREATE JOIN INDEX ji_all AS
SELECT (COUNT(*)(FLOAT)) AS countstar, dim1.d1, dim1_1.d11, dim2.d2,
(SUM(fact.f_d1)(FLOAT)) AS sum_f1
FROM fact, dim1, dim2, dim1_1
WHERE ((fact.f_d1 = dim1.d1)
AND
(fact.f_d2 = dim2.d2))
AND
(dim1.a1 = dim1_1.d11)
GROUP BY dim1.d1, dim1_1.d11, dim2.d2
PRIMARY INDEX (d1);
Note that the results of the aggregate operations COUNT and SUM are both typed as FLOAT
(see “Aggregate Join Indexes” on page 375).
As the bold text in the following EXPLAIN report indicates, the Optimizer uses the join index
ji_all for its query plan in this situation because even though table fact is the parent table of
both tables dim1 and dim2, those tables are joined with fact on foreign key columns in the join
index definition. Similarly, dim1 is joined to dim1_1 in the join index definition on a foreign
key column.
412
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
EXPLAIN SELECT d2, SUM(f_d1)
FROM fact, dim2
WHERE f_d2=d2
GROUP BY 1;
*** Help information returned. 18 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for
read on a RowHash to prevent global deadlock for
HONG_JI.ji_all.
2) Next, we lock HONG_JI.ji_all for read.
3) We do an all-AMPs SUM step to aggregate from
HONG_JI.ji_all by way of an all-rows scan with no
residual conditions, and the grouping identifier in field 1.
Aggregate Intermediate Results are computed globally, then placed
in Spool 3. The size of Spool 3 is estimated with no confidence
to be 3 rows. The estimated time for this step is 0.08 seconds.
4) We do an all-AMPs RETRIEVE step from Spool 3 (Last Use) by way of
an all-rows scan into Spool 1 (group_amps), which is built locally
on the AMPs. The size of Spool 1 is estimated with no confidence
to be 3 rows. The estimated time for this step is 0.07 seconds.
5) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1.
Examples of Exceptions to the General Rules for Extra Tables in the Join
Index Definition
“Example 16” on page 413 and “Example 17” on page 414 illustrate cases that are exceptions
to the general coverage rules for extra tables in a join index definition (see “Restriction on
Coverage by Join Indexes When a Join Index Definition References More Tables Than a
Query” on page 388).
Example 16
In the following example, table t9 is the parent table of tables t7 and t8. Generally, this
relationship disqualifies a join index from covering any query with fewer tables than are
referenced in the definition for that index. However, because t7 and t8 are joined on the FK
columns (y7=x8) in the join index definition, the Optimizer uses the index ji to cover the
query, as you can see by looking at the bold text in the EXPLAIN report:
CREATE SET TABLE t7(
x7 INTEGER NOT NULL,
y7 INTEGER NOT NULL,
z7 INTEGER NOT NULL,
CONSTRAINT r7 FOREIGN KEY (y7) REFERENCES WITH NO CHECK OPTION
t9 (y9))
PRIMARY INDEX (x7);
CREATE SET TABLE t8(
x8 INTEGER NOT NULL,
y8 INTEGER NOT NULL,
z8 INTEGER NOT NULL,
CONSTRAINT r8 FOREIGN KEY (x8) REFERENCES WITH NO CHECK OPTION
t9 (x9));
SQL Reference: Data Definition Statements
413
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
CREATE SET TABLE t9(
x9 INTEGER NOT NULL UNIQUE,
y9 INTEGER NOT NULL,
z9 INTEGER NOT NULL)
UNIQUE PRIMARY INDEX(y9);
CREATE JOIN INDEX ji AS
SELECT x7, y7, x8, y8, x9, y9
FROM t7, t8, t9
WHERE y7=x8
AND
y7=y9
AND
x8=x9;
EXPLAIN SELECT x7, y7, x8, y8
FROM t7, t8
WHERE y7=x8
AND
x7>1;
*** Help information returned. 14 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for
read on a RowHash to prevent global deadlock for HONG_JI.ji.
2) Next, we lock HONG_JI.ji for read.
3) We do an all-AMPs RETRIEVE step from HONG_JI.ji by way
of an all-rows scan with a condition of (
"HONG_JI.ji.x1 > 1") into Spool 1 (group_amps), which
is built locally on the AMPs. The size of Spool 1 is estimated
with no confidence to be 3 rows. The estimated time for this step
is 0.06 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.06 seconds.
Example 17
As with “Example 16” on page 413, this example demonstrates how a join index can be used
to cover a query when one table in the join index definition is a parent of two others if the
tables are joined on foreign key-primary key relationships. t9 is the parent table of both t7 and
t10. But because t7 and t10 are joined with t9 on the same PK column, by transitive closure, t7
and t10 are joined on y7=x10. The Optimizer does select join index ji to cover the query, as
the bold text in the EXPLAIN report for the example query demonstrates:
CREATE SET TABLE t10(
x10 INTEGER NOT NULL,
y10 INTEGER NOT NULL,
z10 INTEGER NOT NULL,
CONSTRAINT r10 FOREIGN KEY (x10) REFERENCES WITH NO CHECK OPTION
t9 (y9))
PRIMARY INDEX x10;
CREATE JOIN INDEX ji AS
SELECT x7, y7, x10, y10, x9, y9
FROM t7, t10, t9
WHERE y7=y9
AND
x10=y9;
414
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE JOIN INDEX
EXPLAIN SELECT x7, y7, x10, y10
FROM t7, t10
WHERE y7=x10
AND
x7>1;
*** Help information returned. 14 rows.
*** Total elapsed time was 1 second.
Explanation
--------------------------------------------------------------------------1) First, we lock a distinct HONG_JI."pseudo table" for
read on a RowHash to prevent global deadlock for HONG_JI.ji.
2) Next, we lock HONG_JI.ji for read.
3) We do an all-AMPs RETRIEVE step from HONG_JI.ji by way
of an all-rows scan with a condition of ("HONG_JI.ji.x1 > 1")
into Spool 1 (group_amps), which is built locally on the AMPs.
The size of Spool 1 is estimated with no confidence to be 3 rows.
The estimated time for this step is 0.06 seconds.
4) Finally, we send out an END TRANSACTION step to all AMPs involved
in processing the request.
-> The contents of Spool 1 are sent back to the user as the result of
statement 1. The total estimated time is 0.06 seconds.
Related Topics
See SQL Reference: Fundamentals for a capsule overview of join indexes and Database Design
for more examples, an extended discussion of the functions and features of join and
partitioned primary indexes, and an overview of disk I/O integrity checking.
See SQL Reference: Statement and Transaction Processing for descriptions of the various forms
of partition elimination.
Also see “CREATE HASH INDEX” on page 316.
SQL Reference: Data Definition Statements
415
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
CREATE MACRO/
REPLACE MACRO
Purpose
Defines a set of statements that are frequently used or that perform a complex operation. The
statements in the macro body are submitted when the macro is invoked by a subsequent
EXECUTE statement.
REPLACE MACRO redefines an existing macro. If the specified macro does not exist,
REPLACE MACRO creates a new macro with that name.
Syntax
A
macro_name
CREATE MACRO
,
database_name.
CM
2048
( parameter_name type declaration
REPLACE MACRO
)
type attribute
A
AS (
SQL_statement ;
USING modifier
)
;
LOCKING modifier
1101G172
where:
Syntax Element …
Specifies …
database_name
the name of the containing database for macro_name if something other than
the current database.
macro_name
the name of the new macro. If a fully qualified name is not specified, the
default database is used.
parameter_name
the name of a parameter that is replaced with a value during macro
execution. UDT columns are valid parameters.
Parameters are restricted to data values. You cannot parameterize database
object names.
When referenced in the macro body, you must prefix a parameter name with
the COLON (:) character.
type_declaration
a data definition or default definition for a parameter.
If you do not assign a default value, you must specify a value for the
parameter at EXECUTE time.
UDTs are valid data types.
For a list of data types see SQL Reference: Data Types and Literals.
416
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Syntax Element …
Specifies …
type_attribute
the data type attributes, such as NOT NULL, UPPERCASE, or TITLE.
For a list of data type attributes see SQL Reference: Data Types and Literals.
USING modifier
one or more variable parameter names. A value is substituted for each
parameter name when the request is processed. Also see “USING Row
Descriptor” in SQL Reference: Data Manipulation Statements. This is an
optional phrase.
USING does not work in a macro when accessed via BTEQ. When running
BTEQ, put USING in the EXECUTE statement.
Including USING in a macro might require special programming. See your
Teradata Field support engineer or the Teradata Support Center for help.
LOCKING modifier
a lock on a database, table, view or row.
The specified lock overrides the default usage lock placed in response to a
request.
Also see “LOCKING Modifier” in SQL Reference: Data Manipulation
Statements.
statement
Specifies an SQL statement. Every statement in the macro body must be
terminated by a SEMICOLON character.
Parameter names referenced in the macro body are prefaced by the COLON
(:) character. The macro body can include EXECUTE statements to invoke
other macros.
ANSI Compliance
CREATE MACRO and REPLACE MACRO are Teradata extensions to the ANSI SQL:2003
standard.
Authorization: CREATE MACRO
You must have the CREATE MACRO privilege on the containing database or user in which the
macro is to be created. The creator of a macro is automatically granted the DROP MACRO
and EXECUTE privileges WITH GRANT OPTION on the macro.
The user creating a macro must have the privileges for all statements it performs.
Once a macro has been created, its immediate owner is the database in which it exists, not the
user who created it. The immediately owning database must have all the appropriate privileges
for executing the macro, including WITH GRANT OPTION.
Access to data via a macro is controlled by the access privileges of its immediate owner, not by
the privileges of its creator. This can be a security issue. See “GRANT (SQL Form)” on
page 1199 and “Security Considerations With CREATE MACRO Privilege” on page 1212 for
details.
The user who performs a macro need not be aware of the tables affected by its performance.
SQL Reference: Data Definition Statements
417
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Authorization: REPLACE MACRO
You must have the DROP MACRO privilege on an existing macro or its containing database
or user to replace it.
You must have the CREATE MACRO privilege on the macro or its containing database or user
if it does not already exist.
The user replacing a macro must have the privileges for all statements it performs.
Once a macro has been replaced, its immediate owner is the database in which it exists, not the
user who replaced it. The immediately owning database must have all the appropriate
privileges for executing the macro, including WITH GRANT OPTION.
Privileges Granted Automatically
The following privileges are granted automatically to the creator of a macro:
•
DROP MACRO
•
EXECUTE
•
GRANT
Restriction on External Authorization From a Macro
You cannot specify CREATE AUTHORIZATION in a macro (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174) because the authorization
password is not saved in either encrypted or unencrypted form. This is because doing so
would compromise the security of the OS logon user ID
If you attempt to do so, the request aborts and an error is returned to the requestor.
Naming Macros
The name of a macro must be unique within its containing user or database. A macro, table,
view, trigger, user-defined function, hash or join index, or stored procedure can take the same
name as the database in which it is created, but two identically named objects, for example, a
macro named TEST and a table named TEST, cannot coexist in the same user or database.
Running a Macro
Running a macro constitutes an implicit transaction. Therefore, in Teradata session mode, a
macro need not be enclosed between BEGIN TRANSACTION and END TRANSACTION
statements.
When the session performing a macro is in ANSI mode, the actions of the macro are
uncommitted until a commit or rollback occurs in subsequent statements unless the macro
body ends with a COMMIT statement. If you define a macro using a COMMIT statement,
then it can be performed only in sessions running in ANSI mode.
The following table explains how to define and use a macro so it can be committed in both
ANSI and Teradata session modes:
418
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
IF a macro is to be performed
in this session mode …
THEN …
ANSI exclusively
add a COMMIT WORK statement to the end of its definition.
both ANSI and Teradata
omit the COMMIT WORK statement from the definition.
Tell users to specify a COMMIT WORK statement explicitly
whenever they perform the macro in ANSI session mode.
Users do not receive responses to individual statements contained in the macro body until all
its statements have been completed successfully. Any object that is referenced by a statement is
locked until the macro transaction is completed, or until the macro is terminated because of a
statement error.
If a macro contains a data definition statement, it cannot contain other statements. A data
definition statement in a macro is not fully resolved until the macro is performed. At that
time, unqualified references to database objects are resolved using the default database for the
user submitting the EXECUTE statement. It is therefore recommended that object references
in a macro data definition statement be fully qualified in the macro body.
Limit On Request Size
The maximum size of the fully expanded text for a macro is 2 Mbyte.
Because expansions of source text in macro definitions are made to fully qualify object names
and to normalize expressions, it is possible for a macro to be defined but also to be unusable
because of stack overflows in the Syntaxer at performance time. In this case, the system returns
an error.
Limits on Attributes Supported in Macro Parameters
Not all of the data attributes that can be specified for table columns can be specified in
macros.
For example, data type declarations and attributes have limited functionality as macro
parameters.
The following data attributes are never valid with macro parameters:
•
CHECK constraints
•
COMPRESS phrase
Resolution of Nonqualified Names
When the CREATE MACRO statement is performed, the system parses the text of the
statements specified in the macro and resolves any names that are not fully qualified in those
statements. Note that nonqualified names in DDL statements in macros are left unresolved.
Consider the following example, in which the default database for user xyz is database abc, and
the database for user lmn is database is def. User xyz defines macro_1 as follows:
SQL Reference: Data Definition Statements
419
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
CREATE MACRO macro_1 AS (
CREATE TABLE mambo
(column_1 INTEGER,
column_2 INTEGER);
);
The fully qualified table name is not specified in the CREATE TABLE statement.
Because CREATE TABLE is a DDL statement, the name of its containing database is not
resolved when the macro is created. Instead, the name is resolved later, when the macro is
performed. The result is that the macro always observes the correct storage hierarchy when it
is performed.
The following table shows how this works:
IF this user performs the macro named
macro_1 …
THEN a table named mambo is created in this database …
xyz
abc
lmn
def
Now suppose that user xyz creates the macro named macro_2 as indicated here:
CREATE MACRO macro_2 AS (
UPDATE tango
SET counter = counter + 1;);
Note that the fully-qualified table name is not specified in the UPDATE statement.
Because UPDATE is a DML statement, it is fully resolved when macro_2 is created.
Subsequently, performing macro_2 causes abc.tango to be updated, whether performed by abc,
lmn, or any other user.
To summarize, the following rules apply to nonqualified names when they are specified in
macros:
•
Nonqualified names in a macro definition are not resolved in DDL statements when the
macro is created. They are not resolved until the macro is performed.
•
Nonqualified names in a macro definition are fully resolved in DML statements when the
macro is created.
Semantic Errors Are Sometimes Not Reported At the Time a Macro Is
Created
The system checks the macro text for syntax errors, but not for semantic errors for EXEC and
DDL statements. Because of this, it is possible to create a macro that is syntactically valid, but
not valid semantically. No message is returned when this occurs.
If there are semantic errors in the macro definition, then a message is returned to the
requestor when you perform it.
420
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
For example, it is possible to create or replace a macro definition that contains an EXEC
request for a macro that is not defined in the system. The following example creates the macro
without returning an error even though the macro it performs, no_such_macro, is not defined
in the database:
CREATE MACRO test_macro AS (
EXEC no_such_macro;);
The system creates the macro as requested. It is only when you attempt to perform test_macro
that you discover the semantic error:
EXEC test_macro;
EXEC test_macro;
*** Failure 3824 Macro 'no_such_macro' does not exist.
Statement# 1, Info =0
*** Total elapsed time was 1 second.
This failure to enforce semantic correctness is restricted to EXEC requests and DDL requests.
If a macro definition contains any DML requests, then the objects those statements reference
must exist or the system aborts the attempt to create the macro.
Because the following CREATE MACRO request contains a reference to the table named
table_1 that does not exist, the system aborts it and returns an error to the requestor:
CREATE MACRO test_macro_2 AS (
SELECT *
FROM table_1;);
CREATE MACRO test_macro_2 AS (SELECT * FROM table_1;);
*** Failure 3807 Object 't1' does not exist.
Statement# 1, Info =0
*** Total elapsed time was 1 second.
Because table_1 does not exist, the system aborts the request.
Employ a USING Request Modifier to Retrieve Data
In designing a macro, employ the USING request modifier to retrieve data from an external
source such as a client data file.
Use a Colon to Specify Value Insertion Variables
Use the COLON character to identify the variables whose values are to be inserted at run time.
For example, if a CREATE MACRO request contains the following VALUES clause:
VALUES (:name, :city, :empno)
then the EXEC request used to execute the macro might contain a clause such as the following:
(name=’Kimble G’, city=’Altadena’, empno=8273)
At run time, the substitutions are made as follows:
VALUES (‘Kimble G’, ‘Altadena’, 8273)
SQL Reference: Data Definition Statements
421
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Using the ASTERISK (*) Character in Macros
A macro defined using the ASTERISK (*) character is forever bound to the definitions of any
tables it references as they were defined at the time the macro was created or replaced.
For example, consider the following macro:
CREATE MACRO get_emp AS (
SELECT *
FROM employee;)
If a column is later added to or removed from the employee table, the following statement still
returns the number of columns that existed in employee when get_emp was defined:
EXEC get_emp;
If columns have been dropped or data types have been changed, performing the macro can
result in an error message or unexpected behavior.
Rules for Using Parameters in Macros
Parameters are values that are entered by the user into the EXEC request for use by the macro
during execution. Note that you cannot pass the names of database objects36 to a macro as
parameters. If you need this functionality, you can use dynamic SQL within a stored
procedure (see SQL Reference: Stored Procedures and Embedded SQL for information on how
to use dynamic SQL within a stored procedure).
Use of parameters is optional in a macro and, when required, are specified as part of the
CREATE MACRO statement.
In defining parameters for a macro, follow the macro name in your CREATE/REPLACE
MACRO statement with the names and attributes of the appropriate parameters. Note that
data type definitions are required for each parameter. Other attributes can include format
specifications or default values. Define new formats via a FORMAT phrase and defaults by a
default control phrase, as necessary.
Teradata Database treats parameters referenced by requests that are contained within a macro
as expressions, not as constant literals, if you specify them where either an ordinal positional
integer number or an expression is valid, such as an ordinary grouping set in a GROUP BY
clause or the ordering specification for an ORDER BY clause.
As a result, Teradata Database does not apply such parameter expressions as constant literals, if
it applies them at all. Instead, you should specify grouping and ordering specifications
explicitly within the body of the macro (see “GROUP BY Clause” and “ORDER BY Clause” in
SQL Data Manipulation Language for details).
If you supply a parameter value in the EXEC request that does not conform to the specified
format, data type, or default value, performance halts with an error message.
The maximum number of parameters you can specify per macro is 2,048.
36. This refers to tables and views and their columns, databases, and so on.
422
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Macro Definitions and Server Character Sets
A macro can contain explicit [VAR]CHARACTER(n) [CHARACTER SET …] clauses. If the
server character set (for example, CHARACTER SET LATIN) is not specified, the macro
definition expands the [VAR]CHARACTER(n) clause.
Expansion is done according to the following rules:
•
If the clause is applied to the macro parameter, it takes the user default server character set
of the creator or modifier of the macro (creator user default server character set).
For example, if the creator user default server character set is Unicode, then the macro is
expanded as shown in the immediately following example:
Original macro definition:
CREATE MACRO mm AS (
column_a CHARACTER(5))
(SELECT :column_a;);
Expanded macro definition:
CREATE MACRO mm AS (
column_a CHARACTER(5) CHARACTER SET UNICODE)
(SELECT :column_a;);
•
If the clause is applied to an expression within the body of the macro, it takes the server
character set of the expression if the expression is typed as CHARACTER. Otherwise, the
server character set is set to the default server character set for the creator user.
For example, if the creator user default server character set is UNICODE, then the macro is
qualified as shown in the immediately following example when it is performed.
Original macro definition:
CREATE TABLE table_2 (
ck CHARACTER(5) CHARACTER SET KANJI1);
CREATE MACRO mm AS (
SELECT ck (CHARACTER(6))
FROM table_2;);
Qualified macro definition:
SELECT ck (CHARACTER(6), CHARACTER SET KANJI1)
FROM table_2;
When the following macro is performed, it is qualified as seen in the SELECT request that
immediately follows it.
Original macro definition:
CREATE MACRO mm AS (
SELECT 123 (CHARACTER(12)););
Qualified macro definition:
SELECT 123 (CHARACTER(6), CHARACTER SET UNICODE);
SQL Reference: Data Definition Statements
423
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
•
If the macro contains a CREATE TABLE or CREATE VIEW with character definition and
the CHARACTER SET clause is omitted, the macro expansion takes the user default server
character set of the user who performs it.
For example, suppose the creator user default server character set is UNICODE. When the
macro definition below is performed by a different user having a user default server
character set of LATIN, then table_1 is created as shown in the immediately following
example.
Original macro definition:
CREATE MACRO tt AS (
CREATE TABLE table_1
(column_l CHARACTER(5)););
Expanded macro definition:
CREATE TABLE table_1 (
column_l CHARACTER(5) CHARACTER SET LATIN NOT CASESPECIFIC);
The same applies to a CREATE VIEW statement within a CREATE MACRO statement.
Why Use Macros?
Performing a macro frees you from having to type the entire set of statements in the macro
body each time the operation defined by these statements is needed. Macros simplify an
operation that is complex or must be performed frequently.
Macro Support for Dates
Validation of date strings in a macro takes place when it is performed. The format of date
strings validate against a DATE column format or the default DATE format, both of which can
change after creating the macro.
To guarantee that dates are properly validated, create or replace your macros by doing either
or both of the following:
•
Specify dates as ANSI date literals instead of strings.
ANSI date literals are accepted as dates for any date operation.
•
Specify the date format you want in a FORMAT phrase in the macro.
Macro Support for Global Temporary and Volatile Tables
You can reference both global temporary tables and volatile tables from a macro.
When you perform a macro that involves a global temporary table, then all references to the
base temporary table are mapped to the corresponding materialized global temporary table
within the current session. Note that this means the same macro, when performed from two
different sessions, can have very different results depending on the content of the materialized
global temporary tables.
When you perform a macro that contains an INSERT statement that inserts rows into a global
temporary table, and that table is not materialized in the current session, then an instance of
the global temporary table is created when the INSERT statement performs.
424
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
When you perform a macro that contains a CREATE VOLATILE TABLE statement, then the
referenced table is created in the current session. If the macro includes a DROP on the named
volatile table, then that table is dropped from the current session.
Macro Support for Large Objects
You can use BLOB and CLOB columns in macros as long as they do not violate the restrictions
on large object use with SQL.
These restrictions are named in the following bulleted list:
•
You cannot create a base table with more than 32 LOB columns, nor can you alter a base
table to have more than 32 LOB columns.
•
You can increase the maximum size of a LOB column up to the system limit, but you
cannot decrease the maximum size of an existing LOB column.
•
LOB columns can only carry the following attributes:
•
NULL
•
NOT NULL
•
TITLE
•
FORMAT
•
LOB columns cannot be a component of any index.
•
A base table containing LOB columns must have at least one non-LOB column to act as its
primary index.
•
The first column specified in a base table definition cannot be a LOB unless a uniqueness
constraint is defined on some non-LOB column set in that table.
•
The uniqueness of a SET base table must be defined on the basis its non-LOB column set
because LOB columns cannot be used to specify row uniqueness.
•
You cannot define integrity constraints on LOB columns, nor can you define integrity
constraints that reference LOB columns.
•
LOB columns can be components of a view subject to the restrictions provided in this list
and the semantics of view definitions.
•
LOB columns can be parameters of a user-defined function.
For more information, see SQL Reference: Data Types and Literals.
Macro Support for UDTs
Macros support both distinct and structured UDTs.
Specifically, macros support the following UDT features:
•
UDT parameters
•
UDT expressions
SQL Reference: Data Definition Statements
425
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Macro Support for Query Bands
Macro support for the SET QUERY_BAND statement is different depending on whether the
Query Band is set for a session or a transaction:
•
SET QUERY_BAND … FOR SESSION is supported in the same way that other DDL
statements are.
•
SET QUERY_BAND … FOR TRANSACTION is supported when there are other
statements in a macro.
Macros and Tactical Queries
Macros can be a very effective method of performing tactical queries. The pros and cons of
using macros to perform tactical queries in various applications and application workloads
are described in detail elsewhere:
•
See Database Design for further information about using macros to perform tactical
queries.
•
See SQL Reference: Data Manipulation Statements, for a comparison of the relative
efficiencies of macros and stored procedures for performing tactical queries.
What REPLACE MACRO Does
In effect, the REPLACE MACRO statement operates as a DROP followed by a CREATE, except
for the handling of access privileges. All access privileges that were granted directly on the
original macro are retained.
If the specified macro does not exist, the REPLACE MACRO statement creates the view or
macro. In this case, the REPLACE statement has the same effect as a CREATE MACRO
statement.
If an error occurs during the replacement of the macro, the existing macro remains in place as
it was prior to the performance of the REPLACE MACRO statement (it is not dropped). This
is analogous to a ROLLBACK on the operation.
426
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Example 1
The following statement creates a macro that first inserts a row for a new employee in the
Employee table, then performs a SELECT statement to verify that the information was entered
correctly:
CREATE MACRO new_emp1 (
number
INTEGER,
name
VARCHAR(12),
dept
INTEGER
DEFAULT 900,
position VARCHAR(12)
sex
CHARACTER,
dob
DATE
FORMAT ’MMMbDDbYYYY’,
edlev
BYTEINT ) AS
(INSERT INTO employee (empno,name,deptno,jobtitle,sex,dob,edlev)
VALUES (:number, :name, :dept, :position, :sex, :dob, :edlev);
-The following select verifies the insert
SELECT *
FROM employee
WHERE empno = :number; );
Use the -- comment construct to include comments in the macro. Text appearing after -- and
up to the end of the line is not performed.
If this macro is performed in ANSI session mode, the INSERT has not been committed. This
is also true in Teradata session mode when the macro is performed as part of an explicit
transaction.
Example 2
This example creates a macro that also inserts a row for a new employee in the employee table,
but then performs an UPDATE request rather than a SELECT request. The UPDATE request
changes the Department table by incrementing the employee count in the row containing a
department number that matches the value of the :dept parameter.
CREATE MACRO new_emp2 (
(number
INTEGER,
name
VARCHAR(12),
dept
INTEGER
DEFAULT 900,
position VARCHAR(12),
sex
CHARACTER,
dob
DATE
FORMAT ’MMMbDDbYYYY’,
edlev
BYTEINT)
AS
(INSERT INTO employee (empno,name,deptno,jobtitle,sex,dob,edlev)
VALUES (:number, :name, :dept, :position, :sex, :dob, :edlev) ;
UPDATE department
SET empcount=empcount+1
WHERE deptno = :dept; );
If this macro is performed in ANSI session mode, the INSERT and UPDATE statements have
not been committed. This is also true in Teradata session mode when the macro is performed
as part of an explicit transaction.
SQL Reference: Data Definition Statements
427
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Example 3
This example replaces the INSERT request with a DELETE request, and the departmental
count of employees in the department table is decremented. The ABORT request terminates
macro execution if the row for the employee being deleted is not present in the employee table.
The example shows a macro designed for use in ANSI mode, and for which the user wants to
commit if the delete and update are successful. Note that the statements in the body of the
macro are entered as one multistatement request. Therefore, if the WHERE condition of the
ROLLBACK statement is met, the entire request is aborted and the value in empcount is
protected.
CREATE MACRO del_emp
(num
SMALLINT
FORMAT ’9(5)’,
dname VARCHAR(12),
dept SMALLINT
FORMAT ’999’) AS
(ABORT ’Name does not exist’
WHERE :num NOT IN (SELECT empno
FROM employee
WHERE name = :dname);
DELETE FROM employee
WHERE name = :dname;
UPDATE Department
SET EmpCount = EmpCount - 1
WHERE DeptNo = :dept;
COMMIT WORK; );
Example 4
You can include a condition for halting execution of a macro by incorporating an ABORT or
ROLLBACK request into the macro. If the specified condition is encountered during
execution, the macro is aborted (the transaction in process is concluded, locks on the tables
are released, changes made to data are backed out, and any spooled output is deleted).
As an example, to restrict the newemp macro from being used to add employees to the
Executive Office, department 300, incorporate an ABORT statement into the macro
specification, as follows:
CREATE MACRO Personnel.new_emp
(number
(SMALLINT
FORMAT ’9(5)’),
name
(VARCHAR(12)),
dept
(SMALLINT
FORMAT ’999’),
position (VARCHAR(12)),
birthdate (DATE
FORMAT ’MMMbDDbYYYY’),
sex
(CHARACTER(1))
education (BYTEINT))
AS
(
(ABORT ’Department 300 not valid’
WHERE :dept = 300;
INSERT INTO employee (empno,name,deptno,jobtitle,dob,sex,edlev)
VALUES (:number,:name,:dept,:position,:birthdate,:sex,:education);
);
428
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Specify the text of an optional error message following the ABORT keyword and enclose it in
APOSTROPHE characters. This message displays on the terminal screen if the macro is
aborted for the specified condition. In this example, the abort condition, :dept = 300, is
specified in the WHERE clause of the ABORT request.
Example 5: REPLACE MACRO
The following example illustrates the use of REPLACE MACRO.
The following request can be used to replace macro new_emp (see “CREATE MACRO/
REPLACE MACRO” on page 416 and “SHOW CAST/ SHOW ERROR TABLE/ SHOW
FUNCTION/ SHOW HASH INDEX/ SHOW JOIN INDEX/ SHOW MACRO/ SHOW
METHOD/ SHOW PROCEDURE/ SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW
TRIGGER/ SHOW TYPE/ SHOW VIEW” on page 1590).
REPLACE MACRO new_emp(name VARCHAR(12) NOT NULL,
street CHARACTER(30),
city
CHARACTER(20),
number INTEGER NOT NULL,
dept
SMALLINT DEFAULT 999) AS
(INSERT INTO employee (name, street, city, empno, deptno)
VALUES (:name, :street, :city, :number, :dept);
UPDATE department
SET empcount = empcount + 1
WHERE deptno = :dept ;);
Example 6: Macro Support for UDT Parameters
The following example demonstrates macro support for UDT parameters.
The p2 parameter of the macro is a structured UDT.
The conversion from VARCHAR to the structured UDT is done using the NEW constructor
invocation expression, which is performed before the macro is actually invoked.
CREATE MACRO m1 (p1 INTEGER, p2 structured_type)
AS (INSERT t1(:p1, :p2););
USING (a INTEGER, b VARCHAR(100))
EXEC m1(:a, NEW structured_type(:b));
Example 7: Same Insert Operation Done Differently
The following example illustrates another way to perform the same insert that was performed
in “Example 6: Macro Support for UDT Parameters” on page 429.
The p2 parameter of the macro is a VARCHAR. It is passed through to the macro. The
conversion is performed within the macro itself using the NEW constructor invocation
expression.
CREATE MACRO m2 (p1 integer, p2 VARCHAR(100))
AS (INSERT t1(:p1, NEW structured_type(:p2)););
USING (a INTEGER, b VARCHAR(100))
EXEC m2(:a, :b);
SQL Reference: Data Definition Statements
429
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE MACRO/ REPLACE MACRO
Example 8: A More Complicated UDT Example Using Parameters
Suppose you have a macro named InsMailList that inserts the first name, last name, and home
address of new customers into a table named MailingAddresses. The value of the customer
home address is defined with a structured UDT named address.
The macro is defined as follows:
CREATE MACRO InsMailList (first VARCHAR(15), last VARCHAR(15),
addr address)
AS (INSERT INTO MailingAddresses VALUES (:first, :last, :addr););
The following trigger adds new California customers to a mailing list whenever a new
customer row is inserted into the Customer table. The insert into the MailingAddresses table is
done using the triggered SQL action statement, the macro InsMailList, which accepts the UDT
parameter address:
CREATE TRIGGER CA_Mailing_list
AFTER INSERT ON Customer
REFERENCING NEW AS NewRow
FOR EACH ROW
WHEN (NewRow.address.state() = 'CA')
EXEC InsMailList(NewRow.Name.Last(), NewRow.Name.First(),
NewRow.address);
Related Topics
See “DROP MACRO/ DROP PROCEDURE/ DROP TABLE/ DROP TRIGGER/ DROP
VIEW” on page 1027.
If a stored procedure would better meet your needs for a specific application than a macro, see
the following references:
430
•
“CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)” on
page 463
•
“CREATE PROCEDURE (SQL Form)/ REPLACE PROCEDURE” on page 529
•
SQL Reference: Stored Procedures and Embedded SQL
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
CREATE METHOD
Purpose
Defines the body of a method that is associated with a user-defined data type (see “CREATE
TYPE (Distinct Form)” on page 906 and “CREATE TYPE (Structured Form)” on page 927).
Syntax
CREATE
A
method_name
METHOD
SYSUDTLIB.
INSTANCE
CONSTRUCTOR
,
A
(
)
parameter
data type
B
AS LOCATOR
parameter_name
B
RETURNS
return
data type
FOR
CAST FROM
C
C
UDF_name
external routine
data type
D
EXTERNAL
NAME
external_function_name
'
F
D
S
C
delimiter
delimiter
method_entry_name
'
I delimiter name_on_server delimiter include_name
L delimiter library_name
O delimiter name_on_server
delimiter object_name
S delimiter name_on_server
delimiter source_name
D
EXTERNAL SECURITY
;
DEFINER
authorization_name
INVOKER
1101A371
SQL Reference: Data Definition Statements
431
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Parameter, Return, and External Function Data Types
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
(fractional_seconds_precision)
WITH TIMEZONE
TIMESTAMP
(fractional_seconds_precision)
WITH TIMEZONE
INTERVAL YEAR
(precision)
TO MONTH
INTERVAL MONTH
(precision)
INTERVAL DAY
TO
(precision)
HOUR
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL HOUR
TO
(precision)
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL MINUTE
(precision)
TO SECOND
(- fractional_seconds_precision - )
INTERVAL SECOND
(precision
)
,fractional_seconds_precision
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
BINARY LARGE OBJECT
(
integer
AS LOCATOR
(
G
K
M
BLOB
UDT_name
SYSUDTLIB.
CHAR
BYTE
( integer )
CHARACTER SET
GRAPHIC
VARCHAR
server_character_set
( integer )
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
CHARACTER LARGE OBJECT
CLOB
432
( integer
( AS LOCATOR
G
K
M
1101D014
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
where:
Syntax element …
Specifies …
INSTANCE
that the object is an instance method. See “About Methods” on page 445
for information about instance methods.
INSTANCE is the default.
CONSTRUCTOR
that the object is a constructor method. See “About Methods” on
page 445 for information about constructor methods.
method_name
the calling name for the method.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the method name as short as possible (see
“Maximum Size of Teradata UNIX MP-RAS Command Line Argument
Affects Names and Number of External Routines in a Database” on
page 448).
method_name must be unique within the SYSUDTLIB database. You
cannot give a method the same name as an existing method or any other
database object contained within the SYSUDTLIB database. See the topic
on naming conventions for details.
method_name must match the spelling and case of its C/C++ method
name exactly if you do not specify a specific_method_name or
external_method_name. This applies only to the definition of the
method, not to its use.
SQL supports function name overloading within the same method class
(see “CLASS function_class” on page 227), so method_name need not be
unique within its class.
Parameter data types and number of parameters are used to distinguish
among different methods within the same class that have the same
method_name.
See SQL Reference: UDF, UDM, and External Stored Procedure
Programming for further information about function overloading.
See the following sections from “CREATE FUNCTION/ REPLACE
FUNCTION” on page 222 for information that is equally applicable to
methods, the necessary changes in terminology being made:
•
•
•
•
•
SQL Reference: Data Definition Statements
“Function Identifiers” on page 244
“Function Name” on page 245
“Function Calling Argument” on page 246
“Function Name Overloading” on page 247
“Parameter Names and Data Types” on page 249
433
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Syntax element …
Specifies …
[parameter_name]
parameter_data_type
[AS LOCATOR]
a parenthetical comma-separated list of data types and optional
parameter names for the variables to be passed to the function.
The maximum number of parameters a method accepts is 128.
BLOB and CLOB types must be represented by a locator (see SQL
Reference: Data Manipulation Statements for a description of locators).
The Teradata Database does not support in-memory LOB parameters: an
AS LOCATOR phrase must be specified for each LOB parameter and
return value.
Note, however, that whenever a LOB that requires data type conversion is
passed to a UDM, the LOB must be materialized for the conversion to
take place.
You must specify opening and closing parentheses even if no parameters
are to be passed to the function.
If you specify one parameter name, then you must specify names for all
the parameters passed to the function.
If you do not specify parameter names, the system assigns unique names
to them in the form P1, P2, …, Pn. These names are used in the
COMMENT statement (see “COMMENT (Comment Placing Form)” on
page 166) and displayed in the report produced by the HELP METHOD
statement (see “HELP METHOD” on page 1493), and appear in the text
of error messages.
The data type associated with each parameter is the type of the parameter
or returned value. All Teradata Database predefined data types and UDTs
are valid. If you specify a UDT, then the current user of the method must
have one of the following privilege sets:
• UDTMETHOD, UDTTYPE, or UDTUSAGE on the SYSUDTLIB
database.
• UDTUSAGE on the specified UDT.
Character data can also specify a CHARACTER SET clause.
For data types that take a length or size specification, like BYTE,
CHARACTER, DECIMAL, VARCHAR, and so on, the size of the
parameter indicates the largest number of bytes that can be passed (see
“Parameter Names and Data Types” on page 249).
434
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Syntax element …
Specifies …
RETURNS
return_data_type
the predefined data type or UDT for the value returned by the method.
The method is responsible for providing the returned data with the
correct type. If the return type is difficult for the method to create, you
should also specify a CAST FROM clause so the system can perform the
appropriate data type conversion (see SQL Reference: Functions and
Operators for more information about using CAST expressions).
The result type has a dictionary entry in DBC.TVFields under the name
RETURN0[n], where n is a sequence of digits appended to RETURN0
rows to make each value unique, ensuring that no user-defined
parameter names are duplicated. The value of n is incremented until it no
longer duplicates a parameter name.
The n subscript is not used if there is no parameter name of RETURN0.
See “Returns Clause” on page 250.
This clause is optional.
If you specify a RETURNS clause, it must be the same as the RETURNS
clause specified for the corresponding CREATE TYPE.
If you do not specify a RETURNS clause for the UDM, then the
RETURNS clause specified for the corresponding CREATE TYPE applies
to this method by default.
CAST FROM
external_data_type
the result type returned by the method that is to be converted to the type
specified by the RETURNS clause.
If you specify a CAST FROM clause, there must be an existing cast from
the “result cast from” data type to the returns data type.
Example:
...RETURNS DECIMAL(9,5) CAST FROM FLOAT...
If external_data_type is a UDT, then the appropriate cast and transform
must be defined to handle its conversion. See “CREATE CAST/
REPLACE CAST” on page 184 and “CREATE TRANSFORM/ REPLACE
TRANSFORM” on page 855.
Whenever a LOB that requires data type conversion is passed to a
method, the LOB must first be materialized for the conversion to take
place.
If external_data_type contains a locator indication, then you cannot
specify a CAST FROM clause for the method.
FOR UDT_name
the name of the UDT with which the method is associated.
The UDT referenced can be either a distinct UDT or a structured UDT.
See “CREATE TYPE (Distinct Form)” on page 906 and “CREATE TYPE
(Structured Form)” on page 927.
SQL Reference: Data Definition Statements
435
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Syntax element …
Specifies …
EXTERNAL
the introduction to the mandatory external method body reference
clause.
This clause can specify two different things:
• The keyword EXTERNAL only.
• The keywords EXTERNAL NAME plus an external method name
(with optional Parameter Style specification)
See “External Body Reference Clause” on page 255.
NAME
external_method_name
the entry point for the method object. This name must be unique within
the SYSUDTLIB database. See “Naming Conventions: Avoiding Name
Clashes Among UDFs, UDMs, and UDTs” on page 439 for details.
Case is significant and must match the C or C++ method name.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the external method name as short as possible
(see “Maximum Size of Teradata UNIX MP-RAS Command Line
Argument Affects Names and Number of External Routines in a
Database” on page 448).
See “External Name Clause” on page 257.
NAME
external_string_literal
a string that specifies the source and object components needed to build
the method.
Depending on the initial code in the sequence, the string specifies either
the C/C++ object name for the method or an encoded name or path for
the components needed to create the method.
The following table briefly documents the codes used to specify
component locations:
IF you specify
this code …
F
THEN the …
string that follows is the entry point name of the C or
C++ method object.
The method_entry_name is the same as the
specific_method_name.
See “Function Entry Name Clause” on page 260.
C
source or object code for the method is stored on the
client and the string that follows is the path to its
location.
See “Client-Server UDF Code Specification” on
page 260.
S
source or object code for the method is stored on the
server and the string that follows is the path to its
location.
See “Client-Server UDF Code Specification” on
page 260.
436
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Syntax element …
Specifies …
NAME
external_string_literal
(continued)
The following table briefly documents the path specifications for the
external method. The character ¡ represents an arbitrary user-defined
delimiter.
You must use the same delimiter throughout the string specification.
File Type
Method object
Syntax
F¡method_entry_point_name
See “Function Entry Name Clause” on page 260
Include
I¡name_on_server¡include_name
See “Include Name Clause” on page 261 for
details.
Library
L¡library_name
See “Library Name Clause” on page 262 for
details.
Object
O¡name_on_server¡object_name
See “Object File Name Clause” on page 262 for
details.
Source
S¡name_on_server¡source_name
See “Source File Name Clause” on page 265 for
details.
To compile the C or C++ method object code with debug symbols for
core dump analysis, specify the delimited character D at any point in the
external string literal. This feature does not produce a useful .so or
.dll file with debug symbols for Linux and Windows systems.
IF you …
THEN the system compiles the method source
code …
specify the D
option
and produces debug symbols.
do not specify the
D option
but does not generate debug symbols.
Generates a core file when a protected mode
UDF crashes.
The purpose of the D option is to provide debug symbol information for
the method when examining a method core file with gdb (see SQL
Reference: UDF, UDM, and External Stored Procedure Programming).
See the user documentation for your C or C++ compiler and debugger
for debugging information.
A side effect of specifying the D option is that linked libraries become
larger because they must also contain all the symbol information.
SQL Reference: Data Definition Statements
437
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Syntax element …
Specifies …
EXTERNAL SECURITY
keywords introducing the external security clause.
This clause is mandatory for methods that perform operating system I/O
operations.
If you do not specify an external security clause, but the method being
defined performs OS I/O, then the results of that I/O are unpredictable.
The most likely outcome is crashing the database, and perhaps crashing
the entire system.
See “External Security Clause” on page 272 for information about the
EXTERNAL SECURITY clause and how it is used for UDFs. This
information generalizes to all external routines, including methods and
external stored procedures.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174 for information about creating authorizations for external
routines.
DEFINER
that the method runs in the client user context of the associated security
authorization object created for this purpose, which is contained within
SYSUDTLIB.
IF you …
THEN …
specify an
authorization
name
an authorization object with that name must be
defined before you can run the method.
do not specify an
authorization
name
you must define a default DEFINER
authorization object.
The default authorization object must be
defined before a user can run the method.
The system reports a warning if the specified authorization name does
not exist at the time the method is created, stating that no authorization
name exists.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174.
authorization_name
an optional authorization name.
The specified authorization object must already be defined (see
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174 for further information) or the system reports an error.
INVOKER
that the method runs in the OS user context with the associated default
authorization object that exists for this purpose.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174.
ANSI Compliance
CREATE METHOD is ANSI SQL-2003 compliant.
438
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Authorization
You must have the UDTMETHOD privilege on the SYSUDTLIB database to create a method
body.
Privileges Granted Automatically
None.
Method Definitions Are Split Between CREATE METHOD And CREATE TYPE
Definitions
Unlike other SQL database objects, the definition for a method is split between CREATE
METHOD and its signature as defined in its associated CREATE TYPE statement (see
“CREATE TYPE (Distinct Form)” on page 906 and “CREATE TYPE (Structured Form)” on
page 927).
Although the definition for a method is generally similar to that of a UDF, unlike a UDF
definition, the following components of a method are defined only in its signature:
•
SPECIFIC NAME clause
•
LANGUAGE clause
•
PARAMETER STYLE clause
•
[NOT] DETERMINISTIC clause
•
SQL data access (NO SQL) clause
Note that the RETURNS clause is defined both in the CREATE METHOD definition and in
the CREATE TYPE signature for the method.
Dropping A Method
There is no DROP METHOD statement that you can use to drop a method body.
Instead, what you must do to drop a method is use the DROP METHOD or DROP SPECIFIC
METHOD option of the ALTER TYPE statement (see “ALTER TYPE” on page 142) to drop
the method signature from its type definition. This action also drops the external routine for
the specified method.
You can also use the REPLACE METHOD statement (see “REPLACE METHOD” on
page 1112) to replace a method body.
Naming Conventions: Avoiding Name Clashes Among UDFs, UDMs, and
UDTs
For UDF, UDM, and UDT names not to clash, they must observe the following two rules:
•
The following column pair must be unique within the DBC.TVM table:
•
•
DatabaseID, TVMNameI
The signature of the following routine must be unique:
•
database_name.routine_name(parameter_list).
SQL Reference: Data Definition Statements
439
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
UDFs, UDMs, and UDTs can have the same SQL names as long as their SPECIFIC names and
associated routine signatures are different.37
The value of database_name is always SYSUDTLIB for UDFs associated with UDTs, including
UDFs used to implement the following functionality on behalf of a UDT:
•
Casts
•
Orderings
•
Transforms
This means that the Database ID column entry is always the same. Because of this, name
uniqueness is dependent on the TVMNameI column value only.
The following list highlights the algorithm used to determine the TVMNameI entry for UDTs
and UDMs named using the Latin character set. Note that all names entered into TVMNameI
have been converted to all capital letters. The TVMNameI entry is always assumed to be 30
bytes long.
•
UDTs created by a CREATE TYPE statement have a SPECIFIC name of at most 30
characters. This name is system-generated based on the specified UDT name.
The system generates the SPECIFIC name by truncating any UDT names that exceed 30
characters to a length of 30 characters.
•
Every time you submit a CREATE TYPE statement, the system automatically generates a
UDF on its behalf to obtain a UDT instance.
This UDF has a TVMNameI column entry constructed as shown by the following process:
a
A specific name of at most 28 characters is generated based on the UDT name.
The specific name is generated as the concatenation of at most the first 20 characters
from the UDT name and the last 8 HEXADECIMAL digits of the system-assigned
routine identifier for the system-generated UDF.
b
The character sequence _C is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
Observer methods, auto-generated on behalf of structured type attributes, have a
TVMNameI column entry constructed as shown by the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
attribute names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the attribute name.
37. In the case of UDTs, the SPECIFIC name reference is to the SPECIFIC names of any method signatures
within a UDT definition, not to the UDT itself, which does not have a SPECIFIC name.
440
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
iv A LOW LINE (underscore) character.
v
b
The last 8 HEXADECIMAL digits of the routine identifier assigned to the observer
instance method.
The character sequence _O is appended after the characters generated by Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
Mutator methods, auto-generated on behalf of structured type attributes, have a
TVMNameI entry constructed as shown by the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
attribute names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated.
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the attribute name.
iv A LOW LINE (underscore) character.
v
b
The last 8 HEXADECIMAL digits of the routine identifier assigned to the mutator
instance method.
The character sequence _M is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
•
End of process.
The system adds the SPECIFIC method names of instance methods created by a CREATE
TYPE, ALTER TYPE, or CREATE METHOD statement to the TVMNameI column in
DBC.TVM.
If the coder of a method does not specify a SPECIFIC method name, then the system
generates one for it with the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
instance method names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the instance method name.
iv A LOW LINE (underscore) character.
v
The last 8 HEXADECIMAL digits of the routine identifier assigned to the instance
method.
SQL Reference: Data Definition Statements
441
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
•
b
The character sequence _R is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
End of process.
The system adds the SPECIFIC method names of constructor methods created by a
CREATE TYPE, ALTER TYPE, or CREATE METHOD statement to the TVMNameI
column in DBC.TVM.
If the coder of a method does not specify a SPECIFIC method name, then the system
generates one for it with the following process:
a
A SPECIFIC name of at most 28 characters is generated based on the UDT and
constructor method names.
The SPECIFIC name is generated as the concatenation of the following elements in the
order indicated:
i
The first 8 characters of the UDT name.
ii
A LOW LINE (underscore) character.
iii The first 10 characters of the constructor method name.
iv A LOW LINE (underscore) character.
v
b
The last 8 HEXADECIMAL digits of the routine identifier assigned to the
constructor method.
The character sequence _C is appended after the characters generated from Stage a.
The remaining characters, up to the 30th character, are filled with SPACE characters.
c
End of process.
The SPECIFIC name of a UDT, UDM or UDF must be unique to avoid name clashes.
FOR this type of external routine …
The SPECIFIC name is …
UDT
always its UDT name.
• UDM
• UDF
user-defined.
There are two exceptions to this rule for structured types:
• System-generated observer methods.
• System-generated mutator methods.
The SPECIFIC names for these are always the same as the
names of the structured UDT attributes on which they operate.
Note that for UDMs, the SPECIFIC name is defined in its
signature within its associated UDT, not within the CREATE
METHOD statement.
442
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Similarly, the signatures of external routines must be unique. The following rules apply:
•
For every UDT you create, the system generates a UDF with the following signature:
SYSUDTLIB.UDT_Name().
No other UDF can have this signature.
•
When you create a UDM, the system treats it as a UDF for which the data type of its first
argument is the same as the UDT on which that UDM is defined.
For example, a UDM named area(), defined on the UDT named circle, would have the
signature SYSUDTLIB.area(circle). It follows that there can be no other UDF with this
same signature.
Given the single database (SYSUDTLIB) Teradata UDT environment, the following rules
apply:
•
A UDT and a SYSUDTLIB UDF with no parameters cannot have the same name.
•
A method for a structured UDT cannot have the same name as any of the attributes for
that type if the signature of the method and the signature of either the observer or mutator
methods for the attribute match.
You must define a transform group for each UDT you create. Because the system creates a
transform group for you automatically when you create a distinct UDT, you cannot create an
additional explicit transform group without first dropping the system-generated transform.
The names of UDT transform groups need not be unique, so you can use the same name for
all transform groups if you wanted to.
Unlike the names for UDTs, UDMs, and UDFs, the names of transform groups are stored in
DBC.UDTTransform rather than DBC.TVM.
Definitions And Purposes Of The Various Method Names
The table on the following page is intended to clarify the definitions and purposes of the
various method name types in the following list:
•
The method name, which is specified in both the CREATE TYPE statement that associates
the method with the UDT and in the CREATE METHOD statement that defines the
method body.
•
The SPECIFIC method name, which is specified in the method signature declaration of
the CREATE TYPE statement that associates the method with the UDT.
•
The method object name, or external method name, which is specified in the EXTERNAL
NAME clause of the CREATE METHOD statement that defines the method body.
SQL Reference: Data Definition Statements
443
444
Method Name
method_name
SPECIFIC method_name
EXTERNAL NAME
external_method_name
Scenario 1
Scenario 2
Scenario 3
Scenario 4
Always specified.
Always specified.
Always specified.
Always specified.
Used as SQL-invoked
routine name.
Used as SQL-invoked
routine name.
Used as SQL-invoked
routine name.
Used as SQL-invoked
routine name.
Specified.
Specified.
Not specified.
Not specified.
Used as the unique
identifying SPECIFIC
name for the method.
Used as the unique
identifying SPECIFIC
name for the method.
System logic generates a
default SPECIFIC
method name and uses it
as the unique identifying
name for the method.
System logic generates a
default SPECIFIC
method name and uses it
as the unique identifying
name for the method.
Specified.
Not specified.
Not specified.
Specified.
Used as the routine entry
point for the method.
The system assumes that
the SPECIFIC method
name is also the routine
entry point for the
method.
The system assumes that
the SPECIFIC method
name is also the routine
entry point for the
method.
Used as the routine entry
point for the method.
The system-generated
SPECIFIC method name
in this scenario is also
used as the routine entry
point for the method.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
About Methods
A user-defined method, also referred to as a method or UDM, is a special kind of UDF that
has the following properties:
•
It is uniquely associated with a particular UDT.
•
It is always created in the SYSUDTLIB database.
•
It is invoked using dot notation, which is in the form of udt_expression.method(…) (see
SQL Reference: Functions and Operators for details).
•
It can be written in either C or C++ (see SQL Reference: UDF, UDM, and External Stored
Procedure Programming for details).
Methods must be defined both as part of the UDT definition38 as specified by its CREATE
TYPE statement (see “Method Definitions Are Split Between CREATE METHOD And
CREATE TYPE Definitions” on page 439, “CREATE TYPE (Distinct Form)” on page 906 and
“CREATE TYPE (Structured Form)” on page 927) and as a separate method body definition
using CREATE METHOD. The definition made by a CREATE METHOD statement actually
declares the method, including its EXTERNAL NAME and EXTERNAL SECURITY
definitions, if required.
Each method has an associated signature, defined as its method name and its declared
parameter list. The method signature must match one of the method signatures that was
specified in the CREATE TYPE statement of the specified UDT (see “CREATE TYPE (Distinct
Form)” on page 906 and “CREATE TYPE (Structured Form)” on page 927), or in a type
redefinition made by an ALTER TYPE statement (see “ALTER TYPE” on page 142).
In other words, there must be a method signature associated with the UDT such that the
following statements are all true:
•
Its method name is the same.
•
Its parameter list is the same.
•
If the method is defined as a CONSTRUCTOR type, then the method signature also
includes the CONSTRUCTOR keyword and its associated UDT must be a structured type.
The declared parameter list is that specified in the method specification of its associated
CREATE TYPE statement. The system generates an augmented parameter list for each method
internally. The augmented parameter list has the associated UDT name, or subject parameter,
as its first parameter and the declared parameter list as its second parameter. Together, these
form the augmented parameter list.
For example, consider the following method specifications for the UDT named udt_name:
CREATE TYPE udt_name
…
CONSTRUCTOR METHOD udt_name(CP1, CP2, …) …,
INSTANCE METHOD M1(MP1, MP2, …) …,
… ;
38. You can add the signatures for newly defined methods to a type definition or drop the signature for an
existing method using the ALTER TYPE statement (see “ALTER TYPE” on page 142).
SQL Reference: Data Definition Statements
445
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
The following table describes the declared and augmented parameter lists for these methods:
Methods
Declared Parameter Lists
Augmented Parameter Lists
Constructor
(CP1, CP2, …)
(udt_name, CP1, CP2, …)
Instance
(MP1, MP2, …)
(udt_name, MP1, MP2, …)
The augmented parameter list is used to check for conflicts between methods specified in
CREATE TYPE or ALTER TYPE statements and existing UDMs and UDFs. The augmented
parameter list is also used in the method resolution process.
Any data type, including LOBs and UDTs, can be declared as a parameter for a method. For
more information on developing methods, see SQL Reference: UDF, UDM, and External
Stored Procedure Programming.
Methods support overloading: multiple methods of a UDT can have the same method name
as long as their parameter lists are different.
Method Types
The Teradata Database supports four types of methods, but only two of those can be created
by a user: instance and constructor. The system does not support static methods.
THIS type of method …
Applies to this type of UDT …
Instance
• Distinct
• Structured
Instance UDMs operate on a specific instance of a UDT.
Constructor
Structured.
Constructor UDTs initialize an instance of a structured UDT.
Instance methods operate on an instance of a UDT, while constructor methods initialize an
instance of a UDT. Instance methods are the more common type. See “Instance Methods” on
page 447 and “Constructor Methods” on page 447 for details.
The other two method types, observer and mutator, are specific types of instance method that
the system generates automatically for each attribute of a structured UDT at the time the UDT
is created. You cannot create either of these using CREATE METHOD. See “CREATE TYPE
(Structured Form)” on page 927 for details.
446
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Instance Methods
Instance methods define an allowable operation on a structured UDT. An instance method
does not operate directly on a UDT, but rather on a particular instance of that UDT.
When an instance method is invoked, a structured type instance is passed as an implicit
subject parameter. This subject parameter is associated with the parameter name, SELF, and is
the reason that you cannot name any UDM parameters using the name SELF.
Instance methods typically manipulate the data attribute set of a structured UDT. Examples of
instance methods include observer and mutator methods.
Constructor Methods
Constructor methods initialize a structured UDT instance with input arguments, creating an
instance value for the type. The ANSI SQL standard defines something called a site, which is
little more than an umbrella name assigned to a large set of different kinds of variables.
Incorporating this definition, a structured UDT is seen to determine a type that is the data
type of a site. Again, this does little more than state that a structured UDT is the data type of
an instance of a variable.
A constructor method, then, assigns specific values to the elements of a site according to the
attributes of the structured UDT that is the data type for that site.
The specification of a constructor method must comply with the following rules:
•
SELF AS RESULT must be specified as part of the method specification in the definition of
the structured UDT (see “CREATE TYPE (Structured Form)” on page 927).
•
The method name must be identical to the name of the structured data type being defined.
•
The return data type specified for CONSTRUCTOR METHOD in the definition of the
structured UDT must be identical to the data type for the corresponding attribute in the
member list of the structured type definition.
Method Signatures
The signature of an instance or constructor method is the partial definition that you must
provide when you create a UDT (see “CREATE TYPE (Distinct Form)” on page 906 and
“CREATE TYPE (Structured Form)” on page 927) or add an instance or constructor method
to the UDT definition (see “ALTER TYPE” on page 142).
The method signature specified for a UDT definition does not completely define an instance or
constructor method; however it does canonically define the following aspects of an instance or
constructor method:
•
The association between the specified method and the UDT being created with a CREATE
TYPE statement (see “CREATE TYPE (Distinct Form)” on page 906 and “CREATE TYPE
(Structured Form)” on page 927).
•
Its specific name, parameter style, SQL data access, and whether it is deterministic or not
(see “Method Definitions Are Split Between CREATE METHOD And CREATE TYPE
Definitions” on page 439). These specifications are all mandatory.
SQL Reference: Data Definition Statements
447
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
The method signature also defines, possibly redundantly, the data type it returns. Note that
the RETURNS clause is mandatory for the method signature, but optional within the clauses
included within CREATE METHOD. The definitions must be identical if both are specified.
A method signature must redundantly and identically specify the following list of items from
its associated method body:
•
Its method name.
•
Its parameter list.
•
The CONSTRUCTOR keyword if it is so defined in the method body of its associated
CREATE METHOD statement.
You do not need to specify the INSTANCE keyword if its associated CREATE METHOD
statement explicitly defines it as such because if no keyword is specified for a method, it is
always assumed to be an instance method by default.
You must always create the method body using the CREATE METHOD statement.
Relationship Among UDMs, UDFs, and External Stored Procedures
External routines, the generic label used for UDFs, table UDFs, methods, and external stored
procedures, are specific variations of one another and share most properties in common,
including being written in a 3GL such as C or C++. See “CREATE FUNCTION/ REPLACE
FUNCTION” on page 222, “CREATE FUNCTION (Table Form)” on page 279, and “CREATE
PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)” on page 463 for
more information.
When an external routine is invoked, the system passes a handle to the UDT argument instead
of the UDT value. Given the handle, an external routine can get, or set, the value of a UDT
argument by means of a set of library functions provided by Teradata (see SQL Reference:
UDF, UDM, and External Stored Procedure Programming).
The ANSI SQL standard contrasts external routines with what it refers to as SQL routines,
which are routines written in the SQL language. The SQL form of stored procedures (see
“CREATE PROCEDURE (SQL Form)/ REPLACE PROCEDURE” on page 529) is an example
of an SQL routine.
Maximum Size of Teradata UNIX MP-RAS Command Line Argument Affects
Names and Number of External Routines in a Database
All of the UDFs, UDMs, and external stored procedures, collectively called external routines, in
a given database are linked into a single dynamic linked library (.so file on Teradata UNIX
MP-RAS).
Whenever you create a new external routine or UDT, the system uses the make utility on the
server to compile the source code and relink the .so file with the new object file and all the
other existing object files.
448
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
On an Teradata UNIX MP-RAS system, the command line argument the system passes to the
make utility to relink the .so file can exceed the maximum command line argument size if you
have many external routines in the database or if their names are long. When this happens, the
system returns an "Arg list too long" error.39
For example, suppose you create a new distinct UDT in the SYSUDTLIB database:
CREATE TYPE really_long_name_for_a_UDT AS INTEGER FINAL;
The system automatically generates functions and methods for the UDT. The output you see
looks something like this:
/usr/bin/cc -Xc -I /tpasw/etc -c -o REALLY_LONG_NAME_FOR_A_UDT_C.o
REALLY_LONG_NAME_FOR_A_UDT_C.cpp
Teradata High Performance C/C++ Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ef_26.so
REALLY_LONG_NAME_FOR_A_UDT_C.o @FileList -ludf -lumm2 -lmw -lm -lcc
If the command line argument that the system passes to the make utility exceeds the
maximum command line argument size, the system returns the following error message:
Error: Arg list too long
(/usr/bin/cc:) Exec of /usr/ccs/bin/ld failed
To work around this limitation, you can do any of the following:
•
Drop all unnecessary UDTs and external routines from the database.
•
Rename UDTs and external routines to shorter names.
•
Change the ARG_MAX kernel parameter to the maximum value, rebuild the kernel, and
reboot the system.
ARG_MAX is an Teradata UNIX MP-RAS system tuning parameter located in the stune
file. This parameter determines the maximum buffer size for passing an argument to a
command line process.
The mtune file documents the minimum, maximum, and current values of ARG_MAX. If
this entry does not exist in stune, the DBA must add it. After changing the ARG_MAX
value, the DBA must do an idbuild to rebuild the kernel and then reboot UNIX. It may be
necessary to perform this procedure on every node of an MPP system.
Note: These workarounds may not work in all cases. For example, if you reach the maximum
number of UDTs allowed on a system, the only solution is to drop enough UDTs to stay within
the system maximum for ARG_MAX.
39. This restriction applies only to Teradata MP-RAS systems. It does not apply to Windows and Linux
systems.
SQL Reference: Data Definition Statements
449
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
When To Run Methods in Unprotected Mode
You should develop your methods in protected mode, which is the default when you create a
new method. Protected and secure modes40 are states in which each instance of a method runs
in a separate process. This is done to protect the system from many common programming
errors such as non-valid pointers, corrupted stacks, and illegal computations such as
divide-by-zero errors that would otherwise crash Teradata Database, produce problems with
memory leakage, or cause other potentially damaging results.
These problems all cause the Teradata Database to crash if they occur in unprotected mode.
Methods can also cause the database to crash in protected and secure modes if they corrupt
the shared data areas between the database and the protected or secure mode method.
Protected and secure modes are designed to be used for the following purposes only:
•
Testing all methods that are in development.
•
Running any methods that cause the OS to consume system resources.41
If a method does not perform operations that cause the OS to consume system resources, then
you should change its protection mode to EXECUTE NOT PROTECTED (see “ALTER
METHOD” on page 28) after it has met your qualification standards for production use.
If a method does perform operations that cause the OS to consume system resources, then you
should always run it in protected mode, even after it has been thoroughly debugged and meets
all your production-level quality standards.
The following table summarizes this information for production-ready methods:
IF a method …
THEN you should run it in this mode …
does not cause the OS to consume system
resources
unprotected.
performs operations that cause the OS to
consume system resources
• protected under the predefined OS user tdatuser.
or
• secure under either of the following users:
• tdatuser
• the OS user specified by the EXTERNAL
SECURITY clause.
The best practice is to develop and test your methods on a non-production test system. You
should run any newly created method several hundred times, both to ensure that it does not
crash the system and to determine any performance issues that could be avoided by alternate
method design and better coding techniques.
40. The difference between a protected mode server and a secure mode server is that a protected mode server
process runs under the predefined OS user tdatuser, while a secure server process runs under the OS user
specified by the UDF in its EXTERNAL SECURITY clause. The two processes are otherwise identical.
41. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
450
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
You can use the cufconfig utility (see Utilities and SQL Reference: UDF, UDM, and External
Stored Procedure Programming) to expand the number of protected or secure mode servers
from the default value of 2 per AMP or PE to a maximum of 20 per AMP or PE vproc. The
minimum is 0.
Protected mode servers consume disk resources as follows:
Number of vprocs Number of protected mode servers 256 K bytes
Total swap space required = ------------------------------------------- × ----------------------------------------------------------------------------------- × ----------------------------Node
vproc
server
In unprotected mode, a method is called directly by the Teradata Database rather than
running as a separate process. You should only alter a new method that does not require the
OS to allocate system context to run in unprotected mode after you have thoroughly tested
and evaluated its robustness and performance impact. Once the newly created
CPU-operations-only method has passed your quality measures and is ready to be put into
production use, you should alter it to run in unprotected mode.
Debug Option
The Teradata Database does not provide specific debugging support for methods; however, for
Teradata MP-RAS UNIX systems only, you can instruct CREATE METHOD to compile the C
or C++ object code for a method with debug symbol information that can then be used by
third party debugging tools to analyze core dumps. The debug option is not supported for
servers running the Windows and Linux operating systems.
The option provides the capability of dumping the contents of local variables in the stack
frame for the method in the core file (see SQL Reference: UDF, UDM, and External Stored
Procedure Programming).
A side effect of specifying the D option is that linked libraries become larger because they
must also contain all the symbol information.
You can specify the D option at any point in the external string literal specification. The D
must be bounded by the same delimiter you use to code the rest of the external string literal
specification.
IF you …
THEN the system …
specify the D option
adds the -G option to code compiled on UNIX systems.
This indicates that the C or C++ compiler should compile the code
with debug symbols.
do not specify the D option
only makes the traceback of the method call available for debugging
purposes.
A side effect of specifying this option is that the .so files for the method are larger than those
generated without the option because they must also contain all the symbolic information.
SQL Reference: Data Definition Statements
451
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
External Security Clause
This clause is mandatory for all methods that perform operating system I/O. Failing to specify
this clause for a method that performs I/O can produce unpredictable results and even cause
the database, if not the entire system, to reset.
Note that authorization_name is an optional Teradata extension to the ANSI SQL:2003
standard.
When a method definition specifies EXTERNAL SECURITY DEFINER, then that method
executes:
•
Under the OS user associated with the specified external authorization using the context of
that user.
IF the UDM runs in this mode …
THEN the OS user must be …
protected
tdatuser, which must be a member of the tdatudf OS group.
secure
an OS user assigned to an authorization name using the
CREATE AUTHORIZATION statement (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174).
The specified OS user must belong to one of the following OS
groups:
• tdatudf.
• the OS group name specified by the
SecureGroupMembership field of the cufconfig utility (see
Utilities).
•
The external security authorization associated with the method must be contained within
the same database as the method (see “CREATE AUTHORIZATION/ REPLACE
AUTHORIZATION” on page 174).
The following rules apply:
•
If you do not specify an authorization name, then you must create a default DEFINER
authorization name before a user attempts to execute the method (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174).
•
If you have specified an authorization name, then an authorization object with that name
must be created before the you can execute the method (see “CREATE
AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174).
The system returns a warning message to the requestor when no authorization name exists
at the time the method is being created.
452
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Example 1
The following example creates the definition for a constructor method named address for the
UDT named address. The external routine for this method is stored on the server at the
location specified in the EXTERNAL NAME clause.
CREATE CONSTRUCTOR METHOD address( VARCHAR(20), CHARACTER(5) )
RETURNS address
FOR address
EXTERNAL NAME
'SO!C:\structured_lib\addr_cons.obj!F!addr_constructor';
Example 2
The following example creates the definition for an instance method named in_state for the
UDT named address. The external routine for this method is stored on the server at the location
specified in the EXTERNAL NAME clause.
CREATE METHOD in_state( CHARACTER(2) )
RETURNS CHARACTER(1)
FOR address
EXTERNAL NAME 'SO!C:\structured_lib\addr_in_state.c!F!in_state';
Example 3
The following example creates the definition for an instance method named timezone for the
UDT named address. The external routine for this method is stored on the server at the location
specified in the EXTERNAL NAME clause.
CREATE METHOD timezone( address )
RETURNS CHARACTER(3)
FOR address
EXTERNAL NAME 'SO!C:\structured_lib\addr_timezone.c!F!in_state';
Example 4
The following example creates the definition for an instance method named toUS for the UDT named
euro. The external routine for this method is stored on the client at the location specified in the
EXTERNAL NAME clause.
CREATE METHOD toUS()
RETURNS us_dollar CAST FROM DECIMAL(8,2)
FOR euro
EXTERNAL NAME
'CO!C:\sys\math.lib!CO!C:\distinct_lib\euro2us.obj!F!toUS';
SQL Reference: Data Definition Statements
453
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE METHOD
Related Topics
The following SQL statements and manuals document various aspects of methods:
•
“ALTER METHOD” on page 28
•
“ALTER TYPE” on page 142
•
“CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on page 174
•
“CREATE CAST/ REPLACE CAST” on page 184
•
“CREATE ORDERING/ REPLACE ORDERING” on page 455
•
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855
•
“CREATE TYPE (Distinct Form)” on page 906
•
“CREATE TYPE (Structured Form)” on page 927
•
“DROP AUTHORIZATION” on page 1001
•
“DROP CAST” on page 1003
•
“DROP ORDERING” on page 1032
•
“DROP TRANSFORM” on page 1041
•
“DROP TYPE” on page 1043
•
“REPLACE METHOD” on page 1112
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
SQL Reference: UDF, UDM, and External Stored Procedure Programming explains how to write
the external routine for a method.
SQL Reference: Functions and Operators documents the dot notation used to invoke methods
within SQL expressions.
454
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
CREATE ORDERING/
REPLACE ORDERING
Purpose
Creates a map ordering routine used to compare UDT values.
Syntax
CREATE
ORDERING
A
UDT_name
FOR
ORDER FULL BY
A
MAP WITH
SYSUDTLIB.
REPLACE
specific_method_name
SPECIFIC METHOD
FOR UDT_name
SYSUDTLIB.
method_name
METHOD
(
(
,
SYSUDTLIB.
INSTANCE
;
data_type
UDT_name
SYSUDTLIB.
specific_function_name
SPECIFIC FUNCTION
SYSUDTLIB.
function_name
FUNCTION
(
(
,
SYSUDTLIB.
data_type
UDT_name
SYSUDTLIB.
1101B359
where:
Syntax element …
Specifies …
FOR
[SYSUDTLIB.]UDT_name
the name of the UDT with which this ordering map is associated.
SPECIFIC FUNCTION
[SYSUDTLIB.]
specific_function_name
the specific name for the UDF that maps the UDT to a predefined
data type value so it can be compared.
FUNCTION [SYSUDTLIB.]
function_name [(data_type)]
the name of the function and its associated data type list that maps
the UDT to a predefined data type value so it can be compared.
SPECIFIC METHOD
[SYSUDTLIB.]
specific_method_name
the specific name for the UDM that maps the UDT to a predefined
data type value so it can be compared.
SQL Reference: Data Definition Statements
The specified method must already be defined. If you specify the
name of a method that has not yet been created, the request aborts
and returns an error to the requestor.
455
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
Syntax element …
Specifies …
[INSTANCE] METHOD
[SYSUDTLIB.]
method_name [(data_type)]
the name of the UDM and its associated data type list that maps the
UDT to a predefined data type value so it can be compared.
FOR
[SYSUDTLIB.]UDT_name
the name of the UDT with which the specified instance UDM is
associated.
The specified method must already be defined. If you specify the
name of a method that has not yet been created, the request aborts
and returns an error to the requestor.
ANSI Compliance
CREATE ORDERING is ANSI SQL:2003-compliant.
REPLACE ORDERING is a Teradata extension to the ANSI SQL:2003 standard.
Authorization
You must have either the UDTTYPE or UDTMETHOD privilege on the SYSUDTLIB
database.
If the map routine you specify is a UDF, then you must also have the EXECUTE FUNCTION
privilege on the UDF, which must be contained within the SYSUDTLIB database.
Privileges Granted Automatically
None.
How REPLACE ORDERING Differs From CREATE ORDERING
The following rules and behaviors differentiate the REPLACE ORDERING and CREATE
ORDERING statements:
•
If you specify REPLACE ORDERING, and the specified ordering exists, the system
replaces it with the new definition.
•
If the specified ordering does not exist and the associated UDT does not have a defined
ordering, then the system creates the specified ordering.
•
If the REPLACE ORDERING statement specifies an ordering for a UDT with which an
existing ordering is associated, the system aborts the request and returns an error to the
requestor because you can specify only one ordering per UDT.
About UDT Ordering Maps
A UDT ordering specifies how two values of the same UDT are to be compared using
relational operators (see SQL Reference: Functions and Operators). The system also uses the
ordering definition for other comparison-related operations such as groupings, orderings,
sorts, and uniqueness determinations.
456
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
An ordering is associated with a UDT by means of the CREATE ORDERING statement. You
must define an ordering for all UDTs that you develop, and you must complete the definition
before you can use it to define the data type of any table. If you attempt to use a UDT in any
way without first creating an ordering for it, the system aborts the request and returns an error
to the requestor.
There are a number of SQL operations that depend on an ordering definition to complete. For
instance, a UDT must have an ordering in order to be used in any of the following operations:
•
•
•
•
•
•
WHERE clause with comparison operators
[NOT] BETWEEN … AND
[NOT] IN
GROUP BY
ORDER BY
SELECT DISTINCT
• Set operators:
• EXCEPT/MINUS
• INTERSECT
• UNION
• COUNT (DISTINCT UDT_column)
• CREATE TABLE when the table contains a
column typed with the UDT
FOR this type of UDT …
THE ordering functionality …
distinct
is generated automatically by the system. a
If the system-generated ordering semantics is adequate, you need not
define explicit ordering functionality using the CREATE ORDERING
statement.
If your applications require different or richer ordering semantics, then
you can specify explicit ordering functionality using CREATE
ORDERING.
structured
must be defined explicitly using the CREATE ORDERING statement.
a. This is not true if the source data type is a LOB. In this case, you must explicitly create an ordering for
the LOB using the CREATE ORDERING statement in conjunction with an appropriate external
routine.
SQL Reference: Data Definition Statements
457
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
Why Teradata Does Not Support The ANSI SQL STATE and RELATIVE
Comparison Options
The ANSI SQL:2003 standard supports 3 comparison options for ordering definitions:
•
MAP
•
RELATIVE
•
STATE
Teradata Database does not support the STATE and RELATIVE comparisons because they do
not mesh well with the Teradata parallel architecture. The issue that makes these options
problematic is that there is a strong relationship between the concepts of equality and the hash
values that Teradata generates for many of its join strategies. Two values that are equal in the
relational use of the concept must generate hash values that are also equal.
The MAP ordering approach enables Teradata to generate internally an appropriate hash value
for the UDT, enabling all Optimizer join strategies to function properly.
Rules for Order Mapping UDFs
If you specify a UDF as the MAP routine for an ordering, it must obey the following rules:
•
It must have one and only one parameter.
•
The data type of the single parameter you specify must be the same as that of the UDT
specified as UDT_name.
•
The result data type must be a predefined data type.
Its predefined data type is valid except the following:
•
BLOB
•
CLOB
•
It must be declared to be DETERMINISTIC.
•
The name you specify for it in the ordering definition must be the name of a UDF
contained within the SYSUDTLIB database.
See “CREATE FUNCTION/ REPLACE FUNCTION” on page 222 for details about UDF
parameters, result data types, and the DETERMINISTIC option.
Rules for Order Mapping UDMs
If you specify a UDM as the MAP routine for an ordering, it must obey the following rules:
•
It must be associated with the UDT for which this ordering is defined.
•
Its declared parameter list must be empty.
•
Its result data type must be a predefined data type.
Its predefined data type is valid except the following:
458
•
BLOB
•
CLOB
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
•
It must be declared to be DETERMINISTIC.
•
The name you specify for it in the ordering definition must be the name of a UDM
contained within the SYSUDTLIB database.
See “CREATE METHOD” on page 431 for details about UDM associations with UDTs,
parameters, result data types, and the DETERMINISTIC option.
Recommendation for Handling Nulls
If you intend to support either of the following things with respect to UDT nulls, then you
should specify a NOT NULL attribute for any column typed with that UDT:
•
Support null UDT attributes.
•
Code MAP ordering routines that can return nulls.
The reason for this recommendation probably is not obvious. The problem that must be dealt
with is that if nulls are permitted in the column and either the MAP ordering routine or the
system-generated observer routine can return nulls, the semantics are somewhat similar to the
situation where you query a column that is specified with the NOT CASESPECIFIC attribute,
where, for identical queries against static data, the results the system returns to the requestor
can vary from request to request.
The ordering routine for a UDT determines both how comparisons of column values are
made and the sort order for values having that user-defined data type.
If you do not follow this recommendation, then it is possible for a column null and a
structured type containing null attributes whose MAP or observer routine returns NULL to be
treated equally. This means that sometimes the system might return a column null in the
result set and other times it might return the non-null structured UDT that contains null
attributes in the result set.
Assuming that the structured UDT named myStructUdtWithNullAttributes was created with
mapping and observer routines that can return nulls, and that the type supports null
attributes (which can be inferred from its name), then a table defined along the lines of the
following example, with all UDT columns specified with the NOT NULL attribute, cannot
behave indeterminately with respect to nulls returned by a query against it:
CREATE TABLE udtTable (
id
INTEGER,
udtColumn myStructUdtWithNullAttributes NOT NULL);
High Level Description of How MAP Routines Work
When you compare two values of a given UDT, the system invokes the MAP routine for each
of them, then compares the returned values from the MAP routine invocations. Returned
values can be specified to have any predefined data type except BLOB or CLOB, and the result
of the UDT data type comparison is the same as the result of comparing the returned
predefined type values.
SQL Reference: Data Definition Statements
459
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
The following notation represents the various types of variables used to specify the values to
be compared and the external routines used to compare them:
•
Let x and y represent the respective values of the UDT to be compared.
•
The following table indicates the notation used to represent UDFs and UDMs:
IF the MAP routine is this type of external
routine …
THEN use the following notation to
represent it …
user-defined method
M()
user-defined function
F
The following table provides examples of the relationships between different values of the
same UDT and the user-defined methods used to operate on them:
IF the following UDM mappings evaluate to TRUE …
THEN the result of x comparison_operator y is …
x.M() = y.M()
x=y
x.M() < Y.M()
x<Y
x.M() <> Y.M()
x <> Y
x.M() > Y.M()
x>Y
x.M() <= Y.M()
x <= Y
x.M() >= Y.M()
x >= Y
The following table provides examples of the relationships between different values of the
same UDT and the user-defined functions used to operate on them:
IF the following UDF mappings evaluate to TRUE …
THEN the result of x comparison_operator y is …
F(x) = F(y)
x=y
F(x) < F(y)
x<y
F(x) <> F(y)
x <> y
F(x) > F(y)
x>y
F(x) <= F(y)
x <= y
F(x) >= F(y)
x >= y
Relationship Between Ordering And Collation Sequence For Character Data
If a mapping routine returns a character data type, the collation that is in effect is always the
effective collation sequence at the time the UDT is accessed, not at the time that the ordering
or UDT was created.
460
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
CREATE ORDERING/REPLACE ORDERING and System-Generated
Constructor UDFs
Note that creating or replacing an ordering also causes the system-generated UDF constructor
function for the UDT to be recompiled invisibly.42
Example 1: Order Mapping Using a UDM
The following order mapping definition for a UDT named circle uses the UDM named
compare_circ(), which is also associated with the circle UDT.
CREATE ORDERING FOR circle
ORDER FULL BY MAP WITH METHOD compare_circ() FOR circle;
Example 2: Order Mapping Using a UDF
The following order mapping definition for a UDT named rectangle uses the UDF named
compare_rect().
CREATE ORDERING FOR rectangle
ORDER FULL BY MAP WITH FUNCTION compare_rect();
Related Topics
See the documentation for the following statements for additional information about UDTs:
•
“ALTER FUNCTION” on page 21
•
“ALTER METHOD” on page 28
•
“ALTER TYPE” on page 142
•
“CREATE CAST/ REPLACE CAST” on page 184
•
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222
•
“CREATE METHOD” on page 431
•
“CREATE TRANSFORM/ REPLACE TRANSFORM” on page 855
•
“CREATE TYPE (Distinct Form)” on page 906
•
“CREATE TYPE (Structured Form)” on page 927
•
“DROP FUNCTION” on page 1013
•
“DROP ORDERING” on page 1032
•
“DROP TRANSFORM” on page 1041
•
“DROP TYPE” on page 1043
•
“RENAME FUNCTION” on page 1104
•
“REPLACE METHOD” on page 1112
•
“HELP CAST” on page 1427
•
“HELP FUNCTION” on page 1464
42. Invisible in that the system does not return any compilation messages unless the compilation fails for some
reason, in which case the system returns an appropriate error message to the requestor.
SQL Reference: Data Definition Statements
461
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE ORDERING/ REPLACE ORDERING
•
“HELP METHOD” on page 1493
•
“HELP TRANSFORM” on page 1557
•
“HELP TYPE” on page 1563
•
“SHOW CAST/ SHOW ERROR TABLE/ SHOW FUNCTION/ SHOW HASH INDEX/
SHOW JOIN INDEX/ SHOW MACRO/ SHOW METHOD/ SHOW PROCEDURE/
SHOW REPLICATION GROUP/ SHOW TABLE/ SHOW TRIGGER/ SHOW TYPE/
SHOW VIEW” on page 1590
See Chapter 5: “SQL DCL Syntax,” for information about the UDTTYPE, UDTMETHOD,
UDTUSAGE, and EXECUTE FUNCTION privileges, particularly as described for the
“GRANT (SQL Form)” on page 1199, particularly the topics “UDT-Related Privileges” on
page 1225 and “EXECUTE FUNCTION Privilege” on page 1224.
Also see SQL Reference: UDF, UDM, and External Stored Procedure Programming for
information about how to write user-defined external routines.
462
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
CREATE PROCEDURE (External Form)/
REPLACE PROCEDURE (External Form)
Purpose
Compiles and installs an external non-SQL stored procedure routine and creates the SQL
definition used to invoke the procedure.
Syntax
CREATE
procedure_name
PROCEDURE
,
A
A
database_name.
REPLACE
256
(
)
B
parameter
data type
parameter_name
DYNAMIC RESULT SETS number_of_sets
IN
OUT
INOUT
B
language_clause
SQL_data_access
C
SQL
TD_GENERAL
JAVA
language_clause
SQL
language_clause
SQL_data_access
TD_GENERAL
JAVA
SQL_data_access
language_clause
PARAMETER STYLE
C
PARAMETER STYLE
SQL_data_access
D
EXTERNAL
NAME
external_function_name
'
F
D
S
C
delimiter
function_entry_name
delimiter
'
I delimiter name_on_server delimiter include_name
L delimiter library_name
O delimiter name_on_server delimiter object_name
P delimiter package_name
S delimiter name_on_server delimiter source_name
' jar_name
java_class_name.
:
A
package_name.
A
java_method_name
'
,
(
java_data_type
(
D
PARAMETER STYLE
SQL Reference: Data Definition Statements
SQL
TD_GENERAL
JAVA
EXTERNAL SECURITY
;
DEFINER
authorization_name
INVOKER
1101C232
463
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Parameter, Return, and External Function Data Types
INTEGER
SMALLINT
BIGINT
BYTEINT
DATE
TIME
(fractional_seconds_precision)
WITH TIMEZONE
TIMESTAMP
(fractional_seconds_precision)
WITH TIMEZONE
INTERVAL YEAR
(precision)
TO MONTH
INTERVAL MONTH
(precision)
INTERVAL DAY
TO
(precision)
HOUR
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL HOUR
TO
(precision)
MINUTE
SECOND
(- fractional_seconds_precision - )
INTERVAL MINUTE
(precision)
TO SECOND
(- fractional_seconds_precision - )
INTERVAL SECOND
(precision
)
,fractional_seconds_precision
REAL
DOUBLE PRECISION
FLOAT
( integer )
DECIMAL
( integer
NUMERIC
)
, integer
BINARY LARGE OBJECT
(
integer
AS LOCATOR
(
G
K
M
BLOB
UDT_name
SYSUDTLIB.
CHAR
BYTE
( integer )
CHARACTER SET
GRAPHIC
VARCHAR
server_character_set
( integer )
CHAR VARYING
VARBYTE
VARGRAPHIC
LONG VARCHAR
LONG VARGRAPHIC
CHARACTER LARGE OBJECT
CLOB
464
( integer
( AS LOCATOR
G
K
M
1101D014
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
The following syntax diagram shows the Java data types that you can specify in the External
Java Reference String for a Java external stored procedure. For each case, the SQL data type is
indicated first. An arrow points to the Java simple map for the type on the main line, with the
Java object mapping type indicated on the line beneath.
Java Simple and Object Mapped Data Types
INTEGER
int
java.lang.Integer
SMALLINT
short
java.lang.Short
BIGINT
long
java.lang.Long
BYTEINT
byte
java.lang.Byte
DATE
not available
java.sql.Date
TIME
not available
java.sql.Time
TIMESTAMP
not available
java.sql.Timestamp
INTERVAL
not available
java.lang.String
REAL
FLOAT
double
java.lang.Double
DOUBLE PRECISION
DECIMAL
not available
NUMERIC
java.math.BigDecimal
BLOB
not available
java.sql.Blob
BYTE
VARBYTE
CHARACTER
VARCHAR
CLOB
not available
byte []
not available
jave.lang.String
not available
java.sql.Clob
1101A507
SQL Reference: Data Definition Statements
465
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
where:
Syntax element …
Specifies …
database_name
an optional database name specified if the stored procedure is to be
created or replaced in a non-default database.
If you do not specify a database name, then the system creates or replaces
the procedure within the current database.
procedure_name
the calling name for the external stored procedure.
procedure_name must match the spelling and case of the C, C++, or Java
procedure name exactly if you do not specify an
external_procedure_name. This applies only to the definition of the
procedure, not to its use.
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the procedure name as short as possible (see
“Maximum Size of Teradata UNIX MP-RAS Command Line Argument
Affects Names and Number of External Routines in a Database” on
page 448).
See the following sections for further information:
•
•
•
•
•
“Function Identifiers” on page 244
“Function Name” on page 245
“Function Calling Argument” on page 246
“Function Name Overloading” on page 247
“Parameter Names and Data Types” on page 249
IN
OUT
INOUT
type of the parameter being specified.
DYNAMIC RESULT
SETS number_of_sets
that number_of_sets of dynamic result sets can be returned.
• IN parameter is input only.
• OUT parameter is output only.
• INOUT can be both input and output.
IN is the default parameter type. If the parameter type is not specified, the
parameter is assumed to be of the IN type.
The range of valid values for number_of_sets is 0 through 15, inclusive.
See “Dynamic Result Sets” on page 481 for details and “Example 5: Result
Set Positioning” on page 521.
parameter_name
parameter_data_type
466
a parenthetical comma-separated list of data types, including UDTs, and
parameter names for the variables to be passed to the procedure.
IF the external routine for the
procedure is written in this
language …
THEN the maximum number of
parameters you can specify in its
parameter list is …
• C
• C++
256
Java
255
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
parameter_name
parameter_data_type
(continued)
BLOB and CLOB types must be represented by a locator (see SQL
Reference: Data Manipulation Statements for a description of locators).
The Teradata Database does not support in-memory LOB parameters: an
AS LOCATOR phrase must be specified for each LOB parameter and
return value in a non-Java stored procedure.
For Java stored procedures, the simple data type references BLOB and
CLOB implicitly refer to BLOB AS LOCATOR and CLOB AS LOCATOR,
respectively. Because of this, you cannot specify an explicit AS LOCATOR
for BLOB and CLOB columns in Java stored procedures.
Note, however, that whenever a LOB that requires data type conversion is
passed to an external procedure, the LOB must be materialized for the
conversion to take place.
You must specify opening and closing parentheses even if no parameters
are to be passed to the procedure.
The data type associated with each parameter is the type of the parameter.
All Teradata Database data types are valid for non-Java procedures.
For Java procedures, neither the GRAPHIC and VARGRAPHIC types nor
UDT parameters are valid.
Character data can also specify a CHARACTER SET clause.
Note that the system does not default to the data type you assign to an
INOUT parameter when the procedure is called. Instead, it defaults to the
smallest data type that can contain the specified input parameter. As a
result, memory overflow errors can occur if an output parameter
returned to an INOUT parameter cannot be contained by the default data
type set for that parameter by the system. See “Memory Considerations
for INOUT Parameters” on page 479 and “CALL” in SQL Reference: Data
Manipulation Statements for details.
For data types that take a length or size specification, like BYTE,
CHARACTER, DECIMAL, VARCHAR, and so on, the length of the
parameter indicates the longest string that can be passed (see “Parameter
Names and Data Types” on page 249).
See SQL Reference: Stored Procedures and Embedded SQL for a list of the
data type encodings that stored procedure IN, INOUT, and OUT
parameters can return to a client application.
SQL Reference: Data Definition Statements
467
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
language_clause
a code that represents the programming language in which the external
procedure is written.
The valid languages for writing external stored procedures are C, C++,
and Java.
Note that Java external stored procedures are supported for 64-bit Linux
and Windows systems only. You cannot create Java external stored
procedures on UNIX systems.
IF the external stored procedure
is written in this language …
THEN the code for the LANGUAGE
clause is …
C
C
C++
CPP
Java
JAVA
You must be specify one of these codes even if the external procedure is
supplied in object form.
If the external procedure object is not written in C, C++, or Java it must
be compatible with C, C++, or Java object code.
This clause is mandatory.
See “Language Clause” on page 250.
468
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
SQL_data_access
whether the external procedure body accesses the database or contains
SQL statements.
Any of the listed option strings is valid for external routines written in the
C, C++, or Java languages. The default is NO SQL.
The valid specifications for the SQL_data_access clause are the following:
Code
CONTAINS SQL
Description
The external routine contains SQL CLIv2 or
Java JDBC calls.
This must be a CLI or Java external stored
procedure that only issues control
statement function calls, such as a CALL
statement to call another stored procedure.
If the external stored procedure defined
with an SQL_data_access of CONTAINS
SQL attempts to read or modify SQL data
or calls a procedure that attempts to do the
same, the system raises the following
SQLSTATE exception:
‘2F004’ reading SQL data not permitted.
MODIFIES SQL DATA
The external routine can perform all SQL
statements that can be called from a stored
procedure.
The following are examples of such
statements:
• DELETE
• INSERT
• UPDATE
NO SQL
The external routine contains no SQL
CLIv2 or Java JDBC function calls.
If an external stored procedure defined with
an SQL_data_access of NO SQL submits
SQL during runtime, the system raises the
following SQLSTATE exception:
‘38001’ containing SQL not permitted.
This is the default.
SQL Reference: Data Definition Statements
469
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
SQL_data_access
(continued)
Code
READS SQL DATA
Description
The external routine can execute SQL
CLIv2 and Java JDBC function calls that
read SQL data from the Teradata Database
only, and cannot execute calls that modify
data inside the Teradata Database.
If an external stored procedure defined with
an SQL_data_access of READS SQL DATA
attempts to modify SQL data, or calls a
procedure that attempts to modify database
data, the system raises the following
SQLSTATE exception:
‘38003’ modifying SQL-data not permitted.
See “SQL Data Access Clause” on page 251.
PARAMETER STYLE
the parameter passing convention to be used when passing parameters to
the procedure.
The specified parameter style must match the parameter passing
convention of the external procedure.
Style
JAVA
Description
If the Java procedure must accept null
arguments, then the EXTERNAL NAME
clause must include the list of parameters
and specify data types that map to Java
objects.
PARAMETER STYLE JAVA must be
specified for all Java procedures.
SQL
Uses indicator variables to pass arguments.
As a result, you can always pass nulls as
inputs and return them in results.
TD_GENERAL
Uses parameters to pass arguments. Can
neither be passed nor return nulls.
If you do not specify a parameter style at this point, you can specify one
with the external body reference.
You cannot specify parameter styles more than once in the same
CREATE/REPLACE PROCEDURE statement.
The default is SQL.
This clause is optional and can only be specified once per external
procedure definition.
See “Parameter Style Clause” on page 253 for more information on
parameter styles.
470
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
EXTERNAL
the introduction to the mandatory external procedure body reference
clause.
This clause can specify four different things:
• The keyword EXTERNAL only.
• The keywords EXTERNAL NAME plus an external procedure name
(with optional Parameter Style specification)
• The keywords EXTERNAL NAME plus a set of external string literals.
• The keywords EXTERNAL NAME plus a set of Java external string
literals.
See “External Body Reference Clause” on page 255.
NAME
external_procedure_name
the entry point for the procedure object.
Case is significant and must match the C or C++ procedure name.
Note that this option is not valid for Java external stored procedures.
Instead, you must specify the EXTERNAL NAME
external_Java_reference_string option (see “NAME
external_Java_reference_ string” on page 474).
If your Teradata Database runs on the Teradata MP-RAS operating
system, you should keep the external procedure name as short as possible
(see “Maximum Size of Teradata UNIX MP-RAS Command Line
Argument Affects Names and Number of External Routines in a
Database” on page 448).
See “External Name Clause” on page 257.
NAME
external_string_literal
a string that specifies the source and object components needed to build
the procedure
Depending on the initial code in the sequence, the string specifies either
the C or C++ procedure object name for the external stored procedure or
an encoded name or path for the components needed to create the
procedure.
SQL Reference: Data Definition Statements
471
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
NAME
external_string_literal
(continued)
The following table briefly documents the codes used to specify
component locations:
IF you
specify this
code …
F
THEN the …
string that follows is the entry point name of the C or
C++ procedure object.
See “Function Entry Name Clause” on page 260.
C
source or object code for the procedure is stored on the
client and the string that follows is the path to its
location.
See “Client-Server UDF Code Specification” on
page 260.
S
source or object code for the procedure is stored on the
server and the string that follows is the path to its
location.
See “Client-Server UDF Code Specification” on
page 260.
The following table briefly documents the path specifications for the
external procedure. The character ¡ represents an arbitrary user-defined
delimiter.
You must use the same delimiter throughout the string specification.
File Type
Procedure object
Syntax
F¡procedure_entry_point_name
See “Function Entry Name Clause” on
page 260 for details.
Include
I¡name_on_server¡include_name
See “Include Name Clause” on page 261 for
details.
Library
L¡library_name
See “Library Name Clause” on page 262 for
details.
Object
O¡name_on_server¡object_name
See “Object File Name Clause” on page 262
for details.
472
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
NAME
external_string_literal
(continued)
File Type
Package
Syntax
P¡package_name
package_name must be CLI for external
stored procedures written in C or C++ that
make SQL calls (see “SQL DATA ACCESS
Clause” on page 493 for details).
package_name must be JDBC for external
stored procedures written in Java that make
SQL calls.
See “Package Name Clause” on page 263 for
details.
Source
S¡name_on_server¡source_name
See “Source File Name Clause” on page 265
for details.
To compile the C or C++ object code with debug symbols for core dump
analysis, specify the delimited character D at any point in the external
string literal. This feature does not produce a useful .so or .dll with debug
symbols for Linux and Windows systems.
IF you …
THEN the system compiles the external
procedure source code …
specify the D option
and produces debug symbols.
Generates a core file when a protected mode
external stored procedure crashes.
do not specify the D
option
but does not generate debug symbols.
The purpose of the D option is to provide debug symbol information for
the external procedure when examining an external procedure core file
with gdb (see SQL Reference: UDF, UDM, and External Stored Procedure
Programming).
See the user documentation for your C or C++ compiler and debugger for
debugging information.
A side effect of specifying the D option is that linked libraries become
larger because they must also contain all the symbol information.
SQL Reference: Data Definition Statements
473
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
NAME
external_Java_reference_
string
a string that specifies the JAR file, Java class within the JAR, and the Java
method within the class to be invoked when the system executes the
procedure in the following format:
‘jar_name:[package_name.]java_class_name.
java_method_name[java_data_type]’
where:
Syntax element …
Specifies …
jar_name
the registered name of the JAR file
associated with the procedure that the
system creates when you call the built-in
external procedure SQLJ.Install_Jar.
package_name
the name and path of an external method
package.
This specification is required only if the Java
class and method you specify are contained
in an external package.
java_class_name
the name of the Java class contained within
the JAR identified by jar_name that
contains the Java method to execute for this
procedure.
If the Java class and method are contained
in an external package, you must fully
qualify java_class_name with the
appropriate package name and path.
java_method_name
the name of the Java method that is
performed when this procedure executes.
java_data_type
a string of one or more Java data types
separated by a COMMA character and
enclosed by LEFT PARENTHESIS and
RIGHT PARENTHESIS characters.
The Java data type list provides a means of
specifying the signature of a particular
implementation of a Java method.
You must specify a Java data type list
whenever the system must choose a
particular overloaded implementation of
the Java method.
A Java data type can be either simple or
object-mapped according to the parameter
mapping rules described in “Data Type
Mapping Between SQL and Java” on
page 487.
Note that java_data_type names are case
sensitive.
474
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
NAME
external_Java_reference_
string (continued)
jar_name and java_class_name must be separated by a COLON character,
while java_class_name and java_method_name are separated by a FULL
STOP character.
For example, if you have a JAR file that is registered in the database with
the name salesreports, the class contained within the JAR is named formal,
and the method to be called within the class is named monthend, the
complete definition for the exact method the system is to invoke when
this procedure is executed is the following external Java reference string:
salesreports:formal.monthend
EXTERNAL SECURITY
keywords introducing the external security clause.
This clause is recommended for procedures that perform operating
system I/O operations because it permits you to specify a particular OS
user under whom the function runs. Otherwise, a protected mode
procedure runs under the generic user tdatuser.
See “When to Specify Unprotected Mode” on page 36, “Authorization
Rules” on page 178, and “When To Run External Stored Procedures in
Unprotected Mode” on page 479.
Also see “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION”
on page 174.
DEFINER
that the procedure runs in the client user context of the associated
security authorization object created for this purpose, which is contained
within the same database as the function.
IF you …
THEN …
specify an authorization
name
an authorization object with that name
must be defined before you can run the
function.
do not specify an
authorization name
you must define a default DEFINER
authorization object.
The default authorization object must be
defined before a user can run the function.
The system reports a warning if the specified authorization name does
not exist at the time the procedure is created, stating that no
authorization name exists.
If you then attempt to execute the procedure, the statement aborts and the
system returns an error to the requestor.
authorization_name
an optional authorization name for this DEFINER as defined by CREATE
AUTHORIZATION.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174.
SQL Reference: Data Definition Statements
475
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Syntax element …
Specifies …
INVOKER
that the procedure runs using the INVOKER authorization associated
with the logged on user who is running the function.
See “CREATE AUTHORIZATION/ REPLACE AUTHORIZATION” on
page 174.
PARAMETER STYLE
See “PARAMETER STYLE” on page 228.
If you do not specify a parameter style at this point, you can specify one
after you specify a language clause and an SQL data access clause.
You cannot specify parameter styles more than once in the same
CREATE/REPLACE PROCEDURE statement.
ANSI Compliance
CREATE PROCEDURE (External Form) is ANSI SQL:2003-compliant with extensions.
Authorization
The privileges required to perform CREATE PROCEDURE (External Form) and REPLACE
PROCEDURE are different:
•
You must have explicit CREATE EXTERNAL PROCEDURE privileges on the database in
which the external procedure is to be contained to perform the CREATE PROCEDURE
(External Form) statement.
The system does not grant the CREATE EXTERNAL PROCEDURE privilege
automatically when you create a database or user: you must grant that privilege explicitly.
CREATE EXTERNAL PROCEDURE is not granted implicitly on the databases and
external procedures owned by a database or user unless the owner also has an explicit
WITH GRANT OPTION privilege defined for itself.
See “CREATE EXTERNAL PROCEDURE Privilege” on page 1222 for further information.
•
You must have explicit DROP PROCEDURE privileges on the external procedure or on
the database in which the external procedure is contained to perform the REPLACE
PROCEDURE statement on an existing external procedure. You do not need the CREATE
EXTERNAL PROCEDURE privilege to replace an external procedure.
•
You must have explicit CREATE EXTERNAL PROCEDURE privileges on the database in
which the external procedure is to be contained to perform the REPLACE PROCEDURE
statement to create a new external procedure.
Privileges Granted Automatically
When you create a new procedure, the system automatically grants the following privileges on
it:
476
•
DROP PROCEDURE
•
EXECUTE PROCEDURE
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Relationship Among UDFs, Table UDFs, and External Stored Procedures
External routines, the generic label used for UDFs, table UDFs, methods, and external stored
procedures, are specific variations of one another and share most properties in common. See
“CREATE FUNCTION/ REPLACE FUNCTION” on page 222 and “CREATE FUNCTION
(Table Form)” on page 279.
Maximum Size of Teradata UNIX MP-RAS Command Line Argument Affects
Names and Number of External Routines in a Database
All of the UDFs, UDMs, and external stored procedures, collectively called external routines, in
a given database are linked into a single dynamic linked library (.so file on Teradata UNIX
MP-RAS).
Whenever you create a new external routine or UDT, the system uses the make utility on the
server to compile the source code and relink the .so file with the new object file and all the
other existing object files.
On an Teradata UNIX MP-RAS system, the command line argument the system passes to the
make utility to relink the .so file can exceed the maximum command line argument size if you
have many external routines in the database or if their names are long. When this happens, the
system returns an "Arg list too long" error.43
For example, suppose you create a new distinct UDT in the SYSUDTLIB database:
CREATE TYPE really_long_name_for_a_UDT AS INTEGER FINAL;
The system automatically generates functions and methods for the UDT. The output you see
looks something like this:
/usr/bin/cc -Xc -I /tpasw/etc -c -o REALLY_LONG_NAME_FOR_A_UDT_C.o
REALLY_LONG_NAME_FOR_A_UDT_C.cpp
Teradata High Performance C/C++ Compiler R3.0c
(c) Copyright 1994-98, Teradata Corporation
(c) Copyright 1987-98, MetaWare Incorporated
/usr/bin/cc -G -Xc -I /tpasw/etc -o libudf_03ef_26.so
REALLY_LONG_NAME_FOR_A_UDT_C.o @FileList -ludf -lumm2 -lmw -lm -lcc
If the command line argument that the system passes to the make utility exceeds the
maximum command line argument size, the system returns the following error message:
Error: Arg list too long
(/usr/bin/cc:) Exec of /usr/ccs/bin/ld failed
43. This restriction applies only to Teradata MP-RAS systems. It does not apply to Windows and Linux
systems.
SQL Reference: Data Definition Statements
477
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
To work around this limitation, you can do any of the following:
•
Drop all unnecessary UDTs and external routines from the database.
•
Rename UDTs and external routines to shorter names.
•
Change the ARG_MAX kernel parameter to the maximum value, rebuild the kernel, and
reboot the system.
ARG_MAX is an Teradata UNIX MP-RAS system tuning parameter located in the stune
file. This parameter determines the maximum buffer size for passing an argument to a
command line process.
The mtune file documents the minimum, maximum, and current values of ARG_MAX. If
this entry does not exist in stune, the DBA must add it. After changing the ARG_MAX
value, the DBA must do an idbuild to rebuild the kernel and then reboot UNIX. It may be
necessary to perform this procedure on every node of an MPP system.
Note: These workarounds might not work in all cases. For example, if you reach the
maximum number of UDTs allowed on a system, the only solution is to drop enough UDTs to
stay within the system maximum for ARG_MAX.
Usage Restrictions for External Stored Procedures
The following restrictions apply to external stored procedures:
•
You cannot perform a CREATE PROCEDURE (External Form) request from an
embedded SQL application.
•
You cannot refer to a recursive view, a WITH clause, or a WITH RECURSIVE clause from
a stored procedure definition.
•
You cannot specify dynamic result sets for a Java procedure.
•
You can only execute SQL function calls using the CLIv2 or JDBC APIs.
•
You cannot write Java strings into columns of a global temporary trace table (see
“CREATE GLOBAL TEMPORARY TRACE TABLE” on page 303) having the following
data types:
•
GRAPHIC
•
VARGRAPHIC
•
LONG GRAPHIC
Though you can define global temporary trace table columns with these types, the Java
language does not support them, so you cannot write Java strings into them from a Java
procedure.
478
•
You can only specify the D (debug) option for external procedures on UNIX MP-RAS
systems.
•
There are also several restrictions for external procedures that are invoked by triggers. See
“Triggers and External Stored Procedures That Make SQL Calls” on page 886 for details.
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Memory Considerations for INOUT Parameters
If the size of an output value returned to an INOUT parameter is larger than the memory the
system had allocated for the input value for that parameter when the procedure was called, the
CALL request fails and returns an overflow error to the requestor.
The following example illustrates this. Suppose you have created a procedure named myintz
with a single INOUT parameter.
CALL myintz(32767);
The smallest data type the system can use to store 32,767 is SMALLINT, so it allocates the 2
bytes required to store a SMALLINT number for the parameter. If this CALL request returns a
value greater than or equal to 32,768 to the INOUT parameter, the system treats it as an
overflow for a SMALLINT irrespective of the data type assigned to the parameter when it was
created, aborts the request, and returns an error because the largest positive value that a
SMALLINT variable can contain is 32,767.
See “CALL” in SQL Reference: Data Manipulation Statements for details and further examples.
When To Run External Stored Procedures in Unprotected Mode
You should develop your external stored procedures in protected mode, which is the default
when you create a new external stored procedure. Protected and secure modes44 are states in
which each instance of a procedure runs in a separate process. This is done to protect the
system from many common programming errors such as non-valid pointers, corrupted
stacks, and illegal computations such as divide-by-zero errors that would otherwise crash the
Teradata Database, produce problems with memory leakage, or cause other potentially
damaging results.
These problems all cause the Teradata Database to crash if they occur in unprotected mode.
External stored procedures can also cause the database to crash in protected and secure modes
if they corrupt the shared data areas between the database and the protected or secure mode
procedure.
Protected and secure modes are designed to be used for the following purposes only:
•
Testing all external procedures that are in development.
•
Running any external procedures that cause the OS to consume system resources.45
If a procedure does not perform operations that cause the OS to consume system resources,
then you should change its protection mode to EXECUTE NOT PROTECTED (see “ALTER
PROCEDURE (External Form)” on page 34) after it has met your qualification standards for
production use.
44. The difference between a protected mode server and a secure mode server is that a protected mode server
process runs under the predefined OS user tdatuser, while a secure server process runs under the OS user
specified by the UDF in its EXTERNAL SECURITY clause. The two processes are otherwise identical.
45. This includes anything that causes the OS to allocate system context, including open files, pipes,
semaphores, tokens, threads (processes), and so on.
SQL Reference: Data Definition Statements
479
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
If a procedure does perform operations that cause the OS to consume system resources, then
you should always run it in protected mode, even after it has been thoroughly debugged and
meets all your production-level quality standards.
The following table summarizes this information for production-ready external stored
procedures:
IF an external stored procedure …
THEN you should run it in this mode …
does not cause the OS to consume system
resources
unprotected.
performs operations that cause the OS to
consume system resources
• protected under the predefined OS user tdatuser.
or
• secure under either of the following users:
• tdatuser
• the OS user specified by the EXTERNAL
SECURITY clause.
The best practice is to develop and test your external stored procedures on a non-production
test system. You should run any newly created external stored procedure several hundred
times, both to ensure that it does not crash the system and to determine any performance
issues that could be avoided by alternate procedure design and better coding techniques.
You can use the cufconfig utility (see Utilities and SQL Reference: UDF, UDM, and External
Stored Procedure Programming) to expand the number of protected or secure mode servers
from the default value of 2 per AMP or PE to a maximum of 20 per AMP or PE vproc. The
minimum is 0.
Protected mode servers consume disk resources as follows:
Number of vprocs Number of protected mode servers 256 K bytes
Total swap space required = ------------------------------------------- × ----------------------------------------------------------------------------------- × ----------------------------Node
vproc
server
In unprotected mode, an external procedure is called directly by the Teradata Database rather
than running as a separate process. You should only alter a new procedure that does not
require the OS to allocate system context to run in unprotected mode after you have
thoroughly tested and evaluated its robustness and performance impact. Once the newly
created CPU-operations-only UDF has passed your quality measures and is ready to be put
into production use, you should alter it to run in unprotected mode.
480
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
Mandatory External Stored Procedure Attributes
All external stored procedures must be created with all the attributes named in the following
list of mandatory elements:
•
Name
•
LANGUAGE C/CPP/Java specification
•
PARAMETER STYLE JAVA specification
•
EXTERNAL NAME external_Java_reference_string specification
All other attributes are optional.
Differences Between CREATE PROCEDURE and REPLACE PROCEDURE
An external stored procedure can be created or replaced using the same syntax except for the
keywords CREATE and REPLACE.
•
If you specify CREATE, the procedure must not exist.
•
If you specify REPLACE, you can either create a new procedure or replace an existing
procedure.
When you replace an existing external procedure, the replaced procedure does not retain the
EXECUTE NOT PROTECTED attribute if one had previously been set using the ALTER
PROCEDURE statement (see “ALTER PROCEDURE (External Form)” on page 34).
The advantage to using REPLACE is that you can avoid having to grant the EXECUTE
privilege again to all users who already had that privilege on the procedure.
Dynamic Result Sets
Dynamic result sets are supported only for external procedures written in C or C++ using the
CLIv2 API. Java external procedures do not support dynamic result sets.
A procedure can return from 0 to 15, inclusive, result sets.
To create a result set to return to the caller or client the external procedure must:
•
Submit the request to the database using the same session, which is the default connection,
as the session for the external procedure.
•
Submit a single statement containing a SELECT request.
•
Specify a SPReturnResult of 1, 2, 3, or 4 in the Options parcel.
•
Specify keep response or positioning.
TO keep the result set until EndRequest is called so that parcels
can then be fetched …
Set keep_resp to this value …
either in random order by row or sequentially within a row
using the DBCAREA settings Positioning-action,
Positioning-statement-number, and Positioning-value
P
in sequential order, the Rewind function called, and then the
parcels can again be fetched
Y
SQL Reference: Data Definition Statements
481
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
When an external procedure executes, result sets created during its execution that match the
conditions in the preceding bulleted list are returned to a calling procedure or client
application of an external procedure if all of the following conditions are met:
•
The external procedure did not send a Cancel parcel to the Dispatcher.
•
The caller or client has indicated its willingness to receive the result sets by setting
DynamicResultSetsAllowed to Y in the Options parcel for the request that called the
procedure.
•
The number of result sets to return is less than or equal to the number_of_sets value in the
DYNAMIC RESULT SETS clause of the CREATE PROCEDURE or REPLACE
PROCEDURE request.
If the external procedure does send a Cancel parcel to the Dispatcher, then the Dispatcher does
not return the result set to the caller or client.
To match the functionality of the SCROLL and NO SCROLL cursors for SQL stored
procedures, the set of rows returned to the caller or client depends on whether the SetPosition
parcel, flavor 157, is sent with the SELECT request.
IF the SetPosition parcel is …
THEN the set of rows returned follows the rules for …
sent
SCROLL cursors.
not sent
NO SCROLL cursors.
For CLIv2 applications, the SetPosition parcel is sent when keep_resp = P.
The external procedure sends the ResultSetCurrentPosition parcel to the Dispatcher Continue
mailbox to indicate the last row read prior to the external procedure completing. If the
procedure never sends the ResultSetCurrentPosition parcel, then the server assumes that while
the entire response might have been sent, none of the rows have been read. This assumption is
made even if the external procedure sends a Continue request to the Teradata Database.
An external procedure can read a dynamic result set by submitting the CALL with the
DynamicResultSetsAllowed field in the Options parcel set to the same session that invoked the
external procedure.
482
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
External Stored Procedures and Large Objects
The Teradata Database does not support returning inline LOBs in an external stored
procedure. If you need an external stored procedure to process inline LOBs, then place an SQL
stored procedure wrapper around the external stored procedure.
To do this, use the following general procedure:
1
Create an SQL stored procedure that calls the external stored procedure and also returns
an inline LOB.
2
Create an external stored procedure that returns the LOB AS LOCATOR to the SQL stored
procedure created in the first step.
The SQL stored procedure then returns the inline LOB to the requestor.
Parameter Names and Data Types
The parameter list contains a list of variables to be passed to the external procedure. The list is
bounded by open and closed parentheses even if there are no parameters to be passed.
IF the external routine for the procedure is written
in this language …
THEN the maximum number of parameters you
can specify in its parameter list is …
• C
• C++
256
Java
255
Parameter names are used by the COMMENT statement (see “COMMENT (Comment
Placing Form)” on page 166) and are reported by the HELP PROCEDURE statement (see
“HELP PROCEDURE” on page 1501). Parameter names, with their associated database and
procedure names, are also returned in the text of error messages when truncation or overflow
errors occur with an external procedure call.
Each parameter type is associated with a mandatory data type to define the type of the
parameter passed to or returned by the external procedure. The specified data type can be any
valid data type (see SQL Reference: Data Types and Literals for a complete list of Teradata
Database SQL data types). Character data types can also specify an associated CHARACTER
SET clause.
For character string types like VARCHAR that might have a different length depending on the
caller, the length of the parameter in the definition indicates the longest string that can be
passed. If there is an attempt to pass a longer string, the result depends on the session mode.
SQL Reference: Data Definition Statements
483
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
The following table summarizes the standard Teradata Database session mode semantics with
respect to character string truncation:
IF the session mode is …
THEN …
ANSI
any pad characters in the string are truncated silently and no truncation
notification is returned to the requestor.
A truncation exception is returned whenever non-pad characters are
truncated.
If there is a truncation exception, then the system does not call the
procedure.
Teradata
the string is truncated silently and no truncation notification message is
returned to the requestor.
See “PARAMETER STYLE Clause” on page 494 and SQL Reference: UDF, UDM, and External
Stored Procedure Programming for details on parameter passing conventions for the
TD_GENERAL and SQL parameter styles.
See Appendix B in SQL Reference: Stored Procedures and Embedded SQL for a list of the data
type encodings that stored procedure IN, INOUT, and OUT parameters can return to a client
application.
LANGUAGE Clause
This mandatory clause specifies the language in which the external procedure source is
written.
The only acceptable language specifications are the following:
•
LANGUAGE C
The specifies that the external procedure is written in the C language.
•
LANGUAGE CPP
This specifies that the external procedure is written in the C++ language.
•
LANGUAGE JAVA
This specifies that the external procedure is written in the Java language.
You can specify the LANGUAGE and SQL DATA ACCESS clauses in any order.
If you only have the object code for your external procedure body, you must ensure that it is
completely compatible with C, C++, or Java object code, even if it was written using a
different programming language.
484
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
External Stored Procedures and SQL
You can execute SQL function calls from external stored procedures using either of the
following languages and APIs:
FOR an external routine written in this language …
You can use this API to execute SQL calls …
• C
• C++
CLIv2
Java
JDBC
This does not mean that you can embed SQL statements within an external stored procedure,
only that you can use standard CLIv2 or JDBC function calls to the appropriate driver, which
then translates those calls into SQL requests and submits them to the Parser for processing.
Note that Teradata Database does not support SQL function calls for channel-attached
platforms.
See Teradata Call-Level Interface Version 2 Reference for Network-Attached Systems or Teradata
Driver for the JDBC Interface User Guide for documentation of the available SQL function
calls.
Restrictions on Declaring an External C++ Stored Procedure
If you specify CPP in the Language Clause, then you must declare the called C++ procedure as
extern “C” to ensure that the procedure name is not converted to an overloaded C++
name, for example:
extern “C”
void my_cpp(long int *input_int, long int *result, char sqlstate[6])
{
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for details.
Rules for Creating a Java External Stored Procedure
Java external stored procedures have two special requirements for creation or replacement that
other types of external stored procedures do not:
•
The user who creates a Java external stored procedure must be the same user who
registered its associated JAR file by calling SQLJ.Install_Jar (see “JAR Files” on page 486
and “SQLJ Database” on page 491). This means that the jar_name you specify when you
create the procedure must refer to a JAR file that you registered. If any other user registered
the JAR file you specify, the CREATE/REPLACE PROCEDURE request aborts and returns
an error to the requestor.
•
The containing database for any Java external stored procedure you create must match the
default database at the time you register its JAR file using SQLJ.Install_Jar.
SQL Reference: Data Definition Statements
485
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
About Java External Stored Procedures
External stored procedures written in Java are supported for 64-bit Linux and Windows
platforms only. You cannot execute Java external stored procedures for UNIX MP-RAS
systems.
When you write the code for an external procedure definition, you indicate that its language is
Java by specifying LANGUAGE JAVA in the mandatory LANGUAGE clause (see “LANGUAGE
Clause” on page 484).
Java external stored procedures execute SQL code using the standard JDBC driver interface.
Because the Java external stored procedure is running on the Teradata Database and is invoked
from within a logged on session, its connection to the database is by means of a default
connection named jdbc:default:connection.
Note that a Java program can create a separate connection to another database, or to the same
database (by means of another session to be logged onto). If an external Java stored procedure
does this, its actions can create an undetectable deadlock.
The ANSI SQL-2003 standard specifies the following set of rules for a Java external stored
procedure:
•
You must compile the Java source code outside the database.
The external Java language routine must be written using the JDBC standard for coding
embedded SQL statements in a Java program.
The resulting class or classes (the byte code) must be placed in a JAR file.
•
You must then register the JAR file with the database.
•
To do this, you call an external stored procedure named SQLJ.Install_Jar.
•
The system creates the Java external stored procedure using its EXTERNAL NAME clause,
which specifies the registered JAR file and its associated Java class.
Once it has been created, you can access the Java routine in the same manner as any external
stored procedure.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for information
on writing Java external stored procedures.
JAR Files
A JAR46 file is an archive of a collection of Java classes in a zip file format and is somewhat
analogous to a DLL file. The classes (byte compiled Java) are referenced when an external Java
routine is created by means of the EXTERNAL NAME clause of CREATE PROCEDURE
(External Form).
JAR files are always created outside of the database. Before you can reference a class, you must
register it and copy it into the SQL environment. Once a JAR has been installed in the
database, you cannot change its content in any way. You are restricted to either deleting a JAR
file or replacing it in its entirety.
46. An initialism for Java ARchive.
486
SQL Reference: Data Definition Statements
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE PROCEDURE (External Form)/ REPLACE PROCEDURE (External Form)
JAR files are available only to the user who installs them by means of a call to the
SQLJ.Install_Jar external stored procedure (see “SQLJ Database” on page 491 and SQL
Reference: UDF, UDM, and External Stored Procedure Programming for information about this
procedure). Analogous to the infrastructure for C and C++ external routines, the system
creates a directory on the server for each database that contains a JAR. Analogous to the fact
that C and C++ DLLs created for one or more external routines in a given database cannot be
accessed by other users or databases, so JAR files created for a Java external routine cannot be
accessed by other users or databases.
There are no specific access rights for JAR files. Therefore, user or database A cannot create an
external stored procedure that references a JAR installed in user or database B. However, user
or database A can be granted access to a Java external stored procedure that has been created
in user or database B by using the same access rights as are used for C and C++ external
routines (see “GRANT (SQL Form)” on page 1199 for information on how to do this).
One way to ensure such ready access to Java external stored procedures is to install all JAR files
and create all Java external stored procedures in the same database and then grant access to
them for all users who must execute them.
See SQL Reference: UDF, UDM, and External Stored Procedure Programming for details.
Data Type Mapping Between SQL and Java
When you create or replace an external Java stored procedure, the system converts all SQL data
types to or from its corresponding Java data type based on the type of parameter mapping.
External stored procedures default to Simple Mapping, where the SQL data types map to Java
primitives or, when an appropriate primitive does not exist, to Java classes. In other words, if
there is a Java type in the Simple Mapping column, the default mapping maps to that type. If
the Simple Mapping column has a not applicable entry for an SQL data type, then the default
mapping maps to the Java class in the Object Mapping column.
If you create or replace a Java external stored procedure that permits nulls to be passed to or
from it, you cannot use simple mapping. To override the default mapping, you must specify
the appropriate Java class from the Object Mapping column in the parameter list of the
EXTERNAL NAME clause.
SQL Reference: Data Definition Statements
487
Chapter 2: SQL DDL Syntax (CREATE AUTHORIZATION - CREATE ROLE)
CREATE