/* * Copyright (c) 2015- Tada AB and other contributors, as listed below. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the The BSD 3-Clause License * which accompanies this distribution, and is available at * http://opensource.org/licenses/BSD-3-Clause * * Contributors: * Chapman Flack */ package org.postgresql.pljava.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.sql.SQLData; // referred to in javadoc /** * Annotation on a PL/Java class to form a User Defined Type that will * become a new PostgreSQL <a href= 'http://www.postgresql.org/docs/current/static/extend-type-system.html' >base type</a>. *<p> * A class marked with this annotation must implement {@link SQLData}, and will * use the methods of that interface to map between its own state and an * internal form that PostgreSQL will store. For that to work, it must also have * a public, no-argument constructor. *<p> * It must also have a public, static * {@code parse(String value, String typeName)} method, and the ubiquitous Java * {@link Object#toString toString} method, which will be used to map between * its own state and an externally-usable, text representation. Note that, while * it may inherit some sort of {@code toString} method from a superclass, there * is a special requirement on {@code toString} for a class that will be a base * UDT: the method must produce exactly what the {@code parse} method can parse. *<p> * A type will be created in SQL with the {@link #name name} and, if specified, * {@link #schema schema} from this annotation. If not specified, the type will * be created with no explicit schema qualification (that is, it will go into * whatever schema heads the {@code search_path} at the time the commands are * executed), and the name will be the simple name of the annotated class. *<p> * Four functions will be declared in SQL, corresponding to the * {@code parse}, {@code toString}, {@link SQLData#readSQL readSQL}, and * {@link SQLData#writeSQL writeSQL} methods of the class. By default, the SQL * names given to them will use the schema, if any, given here for the class, * with the names based on the type name given or defaulted here, with * {@code _in}, {@code _out}, {@code _recv}, and {@code _send} suffixed, * respectively. All of those defaults (and other properties of the functions) * can be individually adjusted by adding {@link Function @Function} annotations * on a method's declaration in this class. *<p> * Other static methods in the class may be exported as SQL functions by * marking them with {@code @Function} in the usual way, and will not have any * special treatment on account of being in a UDT class. If those function * declarations will depend on the existence of this type, or the type must * refer to the functions (as it must for * {@link #typeModifierInput typeModifierInput} or * {@link #typeModifierOutput typeModifierOutput} functions, for example), * appropriate {@link #provides provides}/{@link #requires requires} labels must * be used in their {@code @Function} annotations and this annotation, to make * the order come out right. */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS) public @interface BaseUDT { /** * The supported alignment constraints for the type's internal * representation. */ enum Alignment { CHAR, INT2, INT4, DOUBLE } /** * The supported <a href= 'http://www.postgresql.org/docs/current/static/storage-toast.html' >TOAST strategies</a> for the type's stored representation. * Only {@code PLAIN} is applicable to fixed-length types. */ enum Storage { PLAIN, EXTERNAL, EXTENDED, MAIN } /** * Name of the new type in SQL, if it is not to be the simple name of * the class. By default, the class name will be used, subject to * PostgreSQL's normal case-folding and case-insensitive matching. */ String name() default ""; /** * Schema in which the new type (and, by default, its * input/output/send/receive functions) should be declared. * If not given, the names will not be schema qualified, and will be * created in the schema at the head of the {@code search_path} at * creation time. */ String schema() default ""; /** * One or more arbitrary labels that will be considered 'provided' by the * object carrying this annotation. The deployment descriptor will be * generated in such an order that other objects that 'require' labels * 'provided' by this come later in the output for install actions, and * earlier for remove actions. */ String[] provides() default {}; /** * One or more arbitrary labels that will be considered 'required' by the * object carrying this annotation. The deployment descriptor will be * generated in such an order that other objects that 'provide' labels * 'required' by this come earlier in the output for install actions, and * later for remove actions. */ String[] requires() default {}; /** * The {@code <implementor name>} to be used around SQL code generated * for this type (and for its in/out/recv/send functions, if not * overridden for them). Defaults to {@code PostgreSQL}. Set explicitly * to {@code ""} to emit code not wrapped in an * {@code <implementor block>}. */ String implementor() default ""; /** * A comment to be associated with the type. If left to default, * and the Java class has a doc comment, its first sentence will be used. * If an empty string is explicitly given, no comment will be set. */ String comment() default ""; /** * Name, possibly schema-qualified, of a function to parse type-modifier * strings for this type. Such a function may be implemented in any language * as long as it can accept a single {@code cstring[]} parameter and return * a single non-negative {@code int4}. A static Java method may be used, * following the conventions for a normal PL/Java function. *<p> * Even if the method is defined on the UDT class marked by this annotation, * it is not automatically found or used. It will need its own * {@link Function} annotation giving it a name and a {@code provides} * label, and this annotation must refer to it by that name and include the * label in {@code requires} to ensure the SQL is generated in the right * order. */ String typeModifierInput() default ""; /** * Name, possibly schema-qualified, of a function to format internal * type-modifier codes for display. If it is not provided, PostgreSQL will * simply display numeric modifier codes in parentheses following a type * name. Such a function may be implemented in any language * as long as it can accept a single {@code int4} parameter and return * a {@code cstring} (<em>not</em> a {@code cstring[]}, as you might expect * by analogy to {@link #typeModifierInput typeModifierInput}). A static * Java method may be used, following the conventions for a normal PL/Java * function. *<p> * Even if the method is defined on the UDT class marked by this annotation, * it is not automatically found or used. It will need its own * {@link Function} annotation giving it a name and a {@code provides} * label, and this annotation must refer to it by that name and include the * label in {@code requires} to ensure the SQL is generated in the right * order. */ String typeModifierOutput() default ""; /** * Name, possibly schema-qualified, of a function to gather custom * statistics for this type. It must be implemented in a language allowing * a parameter of type {@code internal}, and return a {@code boolean}. * The details of the necessary API are in <a href= 'http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/commands/vacuum.h' >{@code vacuum.h}</a>. */ String analyze() default ""; /** * Length of the type's internal representation, positive for a fixed * length. {@code VARIABLE} is assumed if this is omitted. */ int internalLength() default -1; /** * If true, indicates that the contents are passed by value rather than by * reference, only possible for fixed-length types no wider than the * PostgreSQL {@code Datum}. */ boolean passedByValue() default false; /** * Alignment constraint for the type in memory. * {@code INT4} is the default and, for variable-length types, also the * minimum (variable-length types begin with an {@code INT4} header). */ Alignment alignment() default Alignment.INT4; /** * The <a href= 'http://www.postgresql.org/docs/current/static/storage-toast.html' >TOAST strategy</a> for the type's stored representation. * Only {@code PLAIN} is applicable to fixed-length types. */ Storage storage() default Storage.PLAIN; /** * Name, possibly schema-qualified, of another SQL type whose * {@code internalLength}, {@code passedByValue}, {@code alignment}, and * {@code storage} properties are used for this type, as a shorthand * alternative to spelling them all out. */ String like() default ""; /** * A category for this type, influencing PostgreSQL's choices for implicit * <a href= 'http://www.postgresql.org/docs/current/static/typeconv-overview.html' >type conversion</a>. * This must be a single character, which PostgreSQL calls "simple ASCII" * and really forces to be in {@code [ -~]}, that is, space to tilde, * inclusive. */ char category() default 'U'; /** * Whether this type is to be "preferred" in its {@link #category}, * for implicit <a href= 'http://www.postgresql.org/docs/current/static/typeconv-overview.html' >type conversion</a> * purposes. Setting true without careful thought can cause perplexing * behaviors. */ boolean preferred() default false; /** * A default value for attributes declared to be of this type. * The value given here will be placed in the {@code CREATE TYPE} command * as a properly-quoted string literal, which must be convertible to a value * of the type (using the {@code parse} function of the class this * annotation marks). */ String defaultValue() default ""; /** * Name, possibly schema-qualified, of an existing type to be accessible by * subscripting this new type as if it were an array (only with zero-based * indexing instead of one-based). Reports from anyone who has seen this * functionality actually work are welcome. */ String element() default ""; /** * Delimiter character to be used between elements when the generic array * routines output an array with this new type as its element type. */ char delimiter() default ','; /** * If true, indicates that column definitions or expressions of this type * may carry a <a href= 'http://www.postgresql.org/docs/current/static/sql-expressions.html#SQL-SYNTAX-COLLATE-EXPRS' >{@code COLLATE} clause</a>. * What is actually done with that information is up to functions that * operate on the new type; nothing happens automatically. */ boolean collatable() default false; }