blob: ddbb5ee28a72268bb855dd015cdd2fe6901aaeb5 [file] [log] [blame]
#ifndef SQLUDR_H
#define SQLUDR_H
/**********************************************************************
*
* File: sqludr.h
* Description: Interface between the SQL engine and routine bodies
* Language: C
*
// @@@ START COPYRIGHT @@@
//
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
//
// @@@ END COPYRIGHT @@@
*
*********************************************************************/
/* Export declaration for DLL functions */
#define SQLUDR_LIBFUNC
#include <stdint.h>
/* C type definitions */
typedef char SQLUDR_CHAR;
typedef int8_t SQLUDR_INT8;
typedef uint8_t SQLUDR_UINT8;
typedef int16_t SQLUDR_INT16;
typedef uint16_t SQLUDR_UINT16;
typedef int32_t SQLUDR_INT32;
typedef uint32_t SQLUDR_UINT32;
typedef int64_t SQLUDR_INT64;
typedef uint64_t SQLUDR_UINT64;
typedef float SQLUDR_REAL;
typedef double SQLUDR_DOUBLE;
/* UDR return codes */
#define SQLUDR_SUCCESS ( 0)
#define SQLUDR_SUCCESS_WITH_WARNING ( 1)
#define SQLUDR_ERROR (-1)
/* NULL indicators */
#define SQLUDR_NULL (-1)
#define SQLUDR_NOTNULL ( 0)
/* To get the NULL indicator for an input value */
#define SQLUDR_GETNULLIND(null_indicator) \
((((char*)(null_indicator))[1] && 0x0080) ? SQLUDR_NULL : SQLUDR_NOTNULL)
/* To set the NULL indicator for a return value */
#define SQLUDR_SETNULLIND(null_indicator) \
(*((short *)(null_indicator)) = -1)
/* To clear the NULL indicator for a return value */
#define SQLUDR_CLEARNULLIND(null_indicator) \
(*((short *)(null_indicator)) = 0)
/* UDR call type */
#define SQLUDR_CALLTYPE_INITIAL ( 1)
#define SQLUDR_CALLTYPE_NORMAL ( 2)
#define SQLUDR_CALLTYPE_FINAL ( 3)
/* Buffer sizes for user-defined errors. These sizes include a null
terminator. */
#define SQLUDR_SQLSTATE_SIZE ( 6)
#define SQLUDR_MSGTEXT_SIZE (256)
/* UDR parameter styles */
enum SQLUDR_PARAMSTYLE
{
SQLUDR_PARAMSTYLE_SQL = 1,
SQLUDR_PARAMSTYLE_SQLROW = 2
};
/* UDR row formats */
enum SQLUDR_ROWFORMAT
{
SQLUDR_ROWFORMAT_EXPLODED = 1
};
/* Collations for character values */
enum SQLUDR_COLLATION
{
SQLUDR_COLLATION_UNKNOWN = 0,
SQLUDR_COLLATION_DEFAULT = 1,
SQLUDR_COLLATION_CZECH = 2,
SQLUDR_COLLATION_CZECH_CI = 3,
SQLUDR_COLLATION_SJIS = 4
};
/* SQLUDR_BUFFER structure */
typedef struct
{
/* Number of data bytes */
SQLUDR_UINT32 length;
SQLUDR_INT32 reserved1;
/* A pointer to the data */
SQLUDR_CHAR *data;
SQLUDR_INT32 reserved2;
} SQLUDR_BUFFER;
/* SQLUDR_STATEAREA structure */
#define SQLUDR_STATEAREA_CURRENT_VERSION ( 1)
#define SQLUDR_STATEAREA_BUFFER_SIZE (4096)
typedef struct
{
/* Version of this structure */
SQLUDR_UINT16 version;
SQLUDR_UINT16 reserved1;
SQLUDR_UINT32 reserved2;
/* A memory region that persists for the lifetime */
/* of the host process. */
SQLUDR_BUFFER host_data;
/* A memory region that persists for the duration */
/* of a single statement execution. */
SQLUDR_BUFFER stmt_data;
SQLUDR_INT64 reserved3;
SQLUDR_INT64 reserved4;
} SQLUDR_STATEAREA;
/* SQLUDR_VC_STRUCT structure for VARCHAR values */
typedef struct
{
/* Number of bytes */
SQLUDR_UINT32 length;
SQLUDR_INT32 reserved1;
/* A pointer to the data */
char *data;
SQLUDR_INT32 reserved2;
} SQLUDR_VC_STRUCT ;
/* SQLUDR_PARAM structure */
#define SQLUDR_PARAM_CURRENT_VERSION 1
typedef struct
{
/* Version of this structure */
SQLUDR_UINT16 version;
/* Parameter type. Will be a value from the SQLTYPE_CODE */
/* enumeration in sqlcli.h. */
SQLUDR_INT16 datatype;
union
{
/* Numeric scale. Valid when the SQL type is NUMERIC or */
/* DECIMAL. */
SQLUDR_INT16 scale;
/* Character set. Valid when the SQL type is any */
/* CHARACTER type. Will be a value from the */
/* SQLCHARSET_CODE enumeration in sqlcli.h. */
SQLUDR_INT16 character_set;
/* Date/time code. Valid when the SQL type is */
/* DATE, TIME, or TIMESTAMP. Will be a value from the */
/* SQLDATETIME_CODE enumeration in sqlcli.h. */
SQLUDR_INT16 datetime_code;
/* Interval type code. Valid when the SQL type is */
/* INTERVAL. Will be a value from the SQLINTERVAL_CODE */
/* enumeration in sqlcli.h. Note that this field is for */
/* future use. INTERVAL parameters are not yet */
/* supported. */
SQLUDR_INT16 interval_code;
} u1;
union
{
/* Numeric precision when the SQL type is NUMERIC or */
/* DECIMAL. Number of digits of fractional precision */
/* when the SQL type is TIME or TIMESTAMP. */
SQLUDR_INT16 precision;
/* Collation. Valid when the SQL type is any CHARACTER */
/* type. Will be a value from the SQLUDR_COLLATION */
/* enumeration in sqludr.h. */
SQLUDR_INT16 collation;
} u2;
/* Null-terminated parameter name */
SQLUDR_CHAR *name;
SQLUDR_INT32 reserved1;
/* Maximum number of bytes in a valid data value */
SQLUDR_UINT32 data_len;
/* Offset within the data region. Valid only for parameter */
/* style SQLROW. */
SQLUDR_UINT32 data_offset;
/* Offset of the two-byte null indicator. Valid only for */
/* parameter style SQLROW. */
SQLUDR_UINT32 ind_offset;
/* Offset of the four-byte VARCHAR length indicator. */
/* Valid only for parameter style SQLROW when datatype */
/* is SQLTYPECODE_VARCHAR_WITH_LENGTH. */
SQLUDR_UINT32 vc_ind_offset;
SQLUDR_UINT8 vc_ind_len;
SQLUDR_INT8 reserved2;
SQLUDR_INT16 reserved3;
SQLUDR_INT32 reserved4;
SQLUDR_INT64 reserved5;
} SQLUDR_PARAM;
#define SQLUDR_ASCENDING 1
#define SQLUDR_DESCENDING -1
#define SQLUDR_ZERO 0
typedef struct
{
SQLUDR_UINT32 num_cols;
SQLUDR_UINT32 *cols_list; /* array of column indexes */
SQLUDR_INT8 *direction; /* defaults to zero, which indicates N/A */
}
SQLUDR_COLS_LIST;
#define SQLUDR_UNIQUE_CONSTRAINT 1
typedef struct
{
SQLUDR_INT8 constraint_type;
SQLUDR_COLS_LIST constraint_cols;
} SQLUDR_CONSTRAINT;
/* SQLUDR_TABLE_PARAM structure */
typedef struct
{
SQLUDR_CHAR *table_name;
SQLUDR_UINT32 num_params ;
SQLUDR_PARAM *params;
SQLUDR_COLS_LIST part_params;
SQLUDR_COLS_LIST order_params;
SQLUDR_UINT32 row_length;
/* the fields below will be zero or NULL at runtime */
SQLUDR_COLS_LIST pred_push_down_params;
SQLUDR_UINT32 num_rows;
SQLUDR_UINT32 *param_uecs; /* number of entries in this list must */
/* match num_params */
/* If a uec is not known for a param the value 0 is used */
SQLUDR_UINT32 num_constraints;
SQLUDR_CONSTRAINT *constraints;
SQLUDR_DOUBLE cost_per_row;
} SQLUDR_TABLE_PARAM;
/* UDRINFO structure */
#define SQLUDR_UDRINFO_CURRENT_VERSION (1)
typedef struct
{
/* Version of this structure */
SQLUDR_UINT16 version;
/* Version of SQL. For example R2.4 = 2400 */
SQLUDR_UINT16 sql_version;
/* Parameter passing style. Will be a value from the */
/* SQLUDR_PARAMSTYLE enumeration. */
SQLUDR_UINT16 param_style;
/* Parameter passing style version */
SQLUDR_UINT16 param_style_version;
/* Row format. Only valid for parameter style SQLROW. */
/* Will be a value from the SQLUDR_ROWFORMAT enumeration. */
SQLUDR_UINT16 row_format;
SQLUDR_UINT16 reserved1;
SQLUDR_UINT16 reserved2;
SQLUDR_UINT16 reserved3;
/* Null-terminated routine name */
SQLUDR_CHAR *routine_name;
SQLUDR_INT32 reserved4;
/* Reserved fields. Can be used for catalog and schema */
/* names in the future */
SQLUDR_INT64 reserved5;
SQLUDR_INT64 reserved6;
/* UUDR action. NULL if this is not a UUDR. */
SQLUDR_CHAR *uudr_action;
SQLUDR_INT32 reserved7;
/* Pass-through inputs */
SQLUDR_UINT32 num_pass_through;
SQLUDR_INT32 reserved8;
SQLUDR_BUFFER *pass_through;
SQLUDR_INT32 reserved9;
/* Null-terminated current user name as returned by CURRENT_USER function*/
SQLUDR_CHAR *current_user_name;
SQLUDR_INT32 reserved10;
/* Null-terminated login user name as returned by SESSION_USER function*/
SQLUDR_CHAR *session_user_name;
SQLUDR_INT32 reserved11;
/* Null-terminated current role name as returned by CURRENT_ROLE function*/
SQLUDR_CHAR *current_role_name;
SQLUDR_INT32 reserved12;
/* Null-terminated query identifier */
SQLUDR_CHAR *query_id;
SQLUDR_INT32 reserved13;
/* Row length and row format. Only valid for parameter */
/* style SQLROW. */
SQLUDR_UINT32 in_row_length;
SQLUDR_UINT32 out_row_length;
/* Descriptive information about each input and output value */
SQLUDR_UINT32 num_inputs;
SQLUDR_UINT32 num_return_values;
SQLUDR_PARAM *inputs;
SQLUDR_INT32 reserved14;
SQLUDR_PARAM *return_values;
SQLUDR_INT32 reserved15;
SQLUDR_INT64 reserved16;
SQLUDR_INT64 reserved17;
SQLUDR_INT64 reserved18;
SQLUDR_INT64 reserved19;
SQLUDR_INT64 reserved20;
SQLUDR_INT64 reserved21;
SQLUDR_INT64 reserved22;
SQLUDR_INT64 reserved23;
/* Instance of tmudfserv */
SQLUDR_UINT32 instance_total;
SQLUDR_UINT32 instance_current;
/* Table related params info */
SQLUDR_UINT32 num_table_inputs ;
SQLUDR_TABLE_PARAM *table_inputs;
} SQLUDR_UDRINFO;
/* TMUDFINFO structure */
#define SQLUDR_TMUDFINFO_CURRENT_VERSION (1)
typedef struct
{
/* Version of this structure */
SQLUDR_UINT16 version;
/* Version of SQL. For example R2.4 = 2400 */
SQLUDR_UINT16 sql_version;
/* Null-terminated routine name */
SQLUDR_CHAR *routine_name;
/* Pass-through inputs */
SQLUDR_UINT32 num_pass_through;
SQLUDR_BUFFER *pass_through;
/* Descriptive information about each input and output value */
SQLUDR_UINT32 num_inputs;
SQLUDR_PARAM *inputs;
SQLUDR_UINT32 num_table_inputs ;
SQLUDR_TABLE_PARAM *table_inputs;
SQLUDR_TABLE_PARAM output_info;
} SQLUDR_TMUDFINFO;
/* SQLUDR_TRAIL_ARGS macro (to simplify function signatures) */
#define SQLUDR_TRAIL_ARGS \
SQLUDR_CHAR sqlstate[SQLUDR_SQLSTATE_SIZE], \
SQLUDR_CHAR msgtext[SQLUDR_MSGTEXT_SIZE], \
SQLUDR_INT32 calltype, \
SQLUDR_STATEAREA *statearea, \
SQLUDR_UDRINFO *udrinfo
/* in case we need to call another function with SQLUDR_TRAIL_ARGS */
#define PASS_ON_SQLUDR_TRAIL_ARGS \
sqlstate, msgtext, calltype, statearea, udrinfo
/* SQLTMUDF Queue State, also defined in
../src/main/java/org/trafodion/sql/udr/UDR.java */
typedef enum SQLUDR_Q_STATE
{
SQLUDR_Q_MORE = 1,
SQLUDR_Q_EOD,
SQLUDR_Q_CANCEL
}SQLUDR_Q_STATE;
typedef void (*SQLUDR_GetNextRow)(char *rowData, /*OUT*/
int tableIndex, /*IN*/
SQLUDR_Q_STATE *queue_state /*OUT*/
);
typedef void (*SQLUDR_EmitRow) (char *rowData, /*IN*/
int tableIndex, /*IN*/
SQLUDR_Q_STATE *queue_state /*IN/OUT*/
);
#define SQLUDR_TMUDF_TRAIL_ARGS \
SQLUDR_CHAR *rowDataSpace1,\
SQLUDR_CHAR *rowDataSpace2,\
SQLUDR_GetNextRow getRow,\
SQLUDR_EmitRow emitRow,\
SQLUDR_TRAIL_ARGS
/* in case we need to call another function with SQLUDR_TMUDF_TRAIL_ARGS */
#define PASS_ON_SQLUDR_TMUDF_TRAIL_ARGS \
rowDataSpace1, rowDataSpace2, getRow, emitRow, PASS_ON_SQLUDR_TRAIL_ARGS
/************************************************/
/* */
/* C++ interface for UDRs */
/* */
/************************************************/
// This interface should eventually replace the C interface
// defined above. We plan to provide a Java interface similar
// to this C++ version.
/**
* @mainpage C++ Interface for Trafodion UDRs
*
* Class tmudr::UDR contains the code written by
* the UDR writer as methods. It also contains default
* implementations for methods the UDR writer chooses
* not to provide. Start with this class if you want to
* explore the interface.
*
* Classes tmudr::UDRInvocationInfo and tmudr::UDRPlanInfo describe
* a specific invocation of a UDR, e.g. number, types and
* values of parameters, UDR name, etc.
*
* For an introduction, see
* https://cwiki.apache.org/confluence/display/TRAFODION/Tutorial%3A+The+object-oriented+UDF+interface
*
*/
// There are no inline functions in this file, except
// for those that return versions, since we want to be
// able to change these classes in an upward-compatible
// way without having to recompile the UDFs.
#ifdef __cplusplus
#include <string>
#include <vector>
// these are classes used internally by Trafodion to set up
// the environment for UDFs, they should not be used
// by UDR writers and are therefore not declared here
class TMUDFInternalSetup;
class SPInfo;
class LmLanguageManagerC;
class LmLanguageManagerJava;
class LmRoutineCppObj;
namespace tmudr
{
// forward declaration
class TableInfo;
// type for a buffer of binary data (e.g. serialized objects)
typedef char * Bytes;
typedef const char * ConstBytes;
/**
* @brief This is the exception to throw when an error occurs in
* a UDR.
*
* The SQLState value must be a value between 38000 and 38999,
* since the SQL standard reserves SQLState class 38 for user-written
* code. SQLState values 38950 to 38999 are reserved for use by
* Trafodion code. Trafodion will produce SQL error code -11252 when
* this exception is thrown.
*/
class UDRException
{
public:
UDRException(int sqlState, const char *printf_format, ...);
UDRException(const char * sqlState, const char *printf_format, ...);
const char *getSQLState() const;
const std::string &getMessage() const;
const std::string &getText() const; // deprecated, use getMessage()
private:
char sqlState_[6];
std::string text_;
};
// Class to help with serialization, note that it is not required
// to inherit from this class in order to participate in serialization.
// UDR writers can ignore this class.
class TMUDRSerializableObject
{
public:
enum Endianness
{
UNKNOWN_ENDIANNESS = 0,
IS_LITTLE_ENDIAN = 1,
IS_BIG_ENDIAN = 2
};
enum TMUDRObjectType
{
UNKNOWN_OBJECT_TYPE = 0,
TYPE_INFO_OBJ = 100,
PARAMETER_INFO_OBJ = 200,
COLUMN_INFO_OBJ = 400,
CARDINALITY_CONSTRAINT_INFO_OBJ = 510,
UNIQUE_CONSTRAINT_INFO_OBJ = 520,
COMP_PREDICATE_INFO_OBJ = 710,
PARTITION_INFO_OBJ = 800,
ORDER_INFO_OBJ = 900,
TUPLE_INFO_OBJ = 1000,
TABLE_INFO_OBJ = 1100,
PARAMETER_LIST_INFO_OBJ = 1200,
UDR_INVOCATION_INFO_OBJ = 1300,
UDR_PLAN_INFO_OBJ = 1400
};
TMUDRSerializableObject(
TMUDRObjectType objectType,
unsigned short version = 1,
unsigned short endianness = IS_LITTLE_ENDIAN);
TMUDRObjectType getObjectType() const;
unsigned short getVersion() const;
Endianness getEndianness() const;
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
void validateObjectType(TMUDRObjectType o);
void validateSerializedLength(int l);
void validateDeserializedLength(int l);
// helper methods to serialize ints and strings, they
// return the length of the serialized information
int serializedLengthOfInt();
int serializedLengthOfLong();
int serializedLengthOfString(const char *s);
int serializedLengthOfString(int stringLength);
int serializedLengthOfString(const std::string &s);
int serializedLengthOfBinary(int binaryLength);
int serializeInt(int i,
Bytes &outputBuffer,
int &outputBufferLength);
int serializeLong(long i,
Bytes &outputBuffer,
int &outputBufferLength);
int serializeString(const char *s,
Bytes &outputBuffer,
int &outputBufferLength);
int serializeString(const char *s,
int len,
Bytes &outputBuffer,
int &outputBufferLength);
int serializeString(const std::string &s,
Bytes &outputBuffer,
int &outputBufferLength);
int serializeBinary(const void *b,
int len,
Bytes &outputBuffer,
int &outputBufferLength);
int deserializeInt(int &i,
ConstBytes &inputBuffer,
int &inputBufferLength);
int deserializeLong(long &i,
ConstBytes &inputBuffer,
int &inputBufferLength);
int deserializeString(const char *&s,
int &stringLength,
bool makeACopy,
ConstBytes &inputBuffer,
int &inputBufferLength);
int deserializeString(std::string &s,
ConstBytes &inputBuffer,
int &inputBufferLength);
int deserializeBinary(const void **b,
int &binaryLength,
bool makeACopy,
ConstBytes &inputBuffer,
int &inputBufferLength);
TMUDRObjectType getNextObjectType(ConstBytes inputBuffer,
int inputBufferLength);
private:
struct headerFields {
int objectType_;
int totalLength_;
unsigned short version_;
unsigned short endianness_;
int flags_;
int filler_;
} v_;
};
/**
* @brief Data types in the UDR interface
*
* Describes an SQL data type and the corresponding C/C++ type,
* used for scalar parameters, columns of input rows and
* columns of result rows.
*/
class TypeInfo : public TMUDRSerializableObject
{
public:
/** SQL data types */
enum SQLTypeCode
{
UNDEFINED_SQL_TYPE,
SMALLINT, ///< 16 bit integer
INT, ///< 32 bit integer
LARGEINT, ///< 64 bit integer
NUMERIC, ///< Numeric with decimal precision
DECIMAL_LSE, ///< Decimal, leading sign embedded
SMALLINT_UNSIGNED, ///< unsigned 16 bit integer
INT_UNSIGNED, ///< unsigned 32 bit integer
NUMERIC_UNSIGNED, ///< unsigned numeric
DECIMAL_UNSIGNED, ///< unsigned decimal
REAL, ///< 4 byte floating point number
DOUBLE_PRECISION, ///< 8 byte floating point number
CHAR, ///< fixed length character types.
VARCHAR, ///< varying length character types.
DATE, ///< date
TIME, ///< time
TIMESTAMP, ///< timestamp
INTERVAL, ///< interval
BLOB, ///< Binary Large Object
CLOB, ///< Character Large Object
TINYINT, ///< 8 bit integer
TINYINT_UNSIGNED, ///< unsigned 8 bit integer
BOOLEAN ///< boolean, 1 byte 0 or 1
};
/** Classes of types defined in the SQL standard */
enum SQLTypeClassCode
{
CHARACTER_TYPE, ///< char and varchar types
NUMERIC_TYPE, ///< exact and approximate numerics
DATETIME_TYPE, ///< date/time/timestamp
INTERVAL_TYPE, ///< day/month or hour/second intervals
LOB_TYPE, ///< BLOBs and CLOBs
BOOLEAN_TYPE, ///< Boolean
UNDEFINED_TYPE_CLASS ///< undefined value
};
/** More detailed type information, but not as detailed as the actual type */
enum SQLTypeSubClassCode
{
FIXED_CHAR_TYPE, ///< CHAR types
VAR_CHAR_TYPE, ///< VARCHAR type
EXACT_NUMERIC_TYPE, ///< Exact numeric
APPROXIMATE_NUMERIC_TYPE, ///< Approximate numeric (floating point)
DATE_TYPE, ///< Date
TIME_TYPE, ///< Time
TIMESTAMP_TYPE, ///< Timestamp (date + time
///< + optional fractional seconds)
YEAR_MONTH_INTERVAL_TYPE, ///< Intervals involving year and month
DAY_SECOND_INTERVAL_TYPE, ///< Intervals involving
///< days/hours/minutes/seconds
LOB_SUB_CLASS, ///< LOBs
BOOLEAN_SUB_CLASS, ///< Boolean
UNDEFINED_TYPE_SUB_CLASS ///< undefined value
};
/** Character sets */
enum SQLCharsetCode
{
UNDEFINED_CHARSET,
CHARSET_ISO88591, ///< ISO 8859-1, single byte western European characters
CHARSET_UTF8, ///< UTF-8, 1-4 byte Unicode encoding, length is in bytes
CHARSET_UCS2 ///< UCS-2, 16 bit Unicode encoding, tolerates UTF-16
};
/** Collations */
enum SQLCollationCode
{
UNDEFINED_COLLATION, ///< undefined value
SYSTEM_COLLATION ///< System collation, which is a binary
///< collation, except that it ignores
///< trailing blanks
};
/** Start and end fields of interval columns */
// Note: same values as SQLINTERVAL_CODE in file sql/cli/sqlcli.h
enum SQLIntervalCode
{
UNDEFINED_INTERVAL_CODE = 0,
INTERVAL_YEAR = 1,
INTERVAL_MONTH = 2,
INTERVAL_DAY = 3,
INTERVAL_HOUR = 4,
INTERVAL_MINUTE = 5,
INTERVAL_SECOND = 6,
INTERVAL_YEAR_MONTH = 7,
INTERVAL_DAY_HOUR = 8,
INTERVAL_DAY_MINUTE = 9,
INTERVAL_DAY_SECOND = 10,
INTERVAL_HOUR_MINUTE = 11,
INTERVAL_HOUR_SECOND = 12,
INTERVAL_MINUTE_SECOND = 13
};
TypeInfo(const TypeInfo &type);
TypeInfo(SQLTypeCode sqltype = UNDEFINED_SQL_TYPE,
int length = 0,
bool nullable = false,
int scale = 0,
SQLCharsetCode charset = CHARSET_UTF8,
SQLIntervalCode intervalCode = UNDEFINED_INTERVAL_CODE,
int precision = 0,
SQLCollationCode collation = SYSTEM_COLLATION);
// this constructor should not be used by UDR writers
TypeInfo(SQLTypeCode sqltype,
bool nullable,
int scale,
SQLCharsetCode charset,
SQLIntervalCode intervalCode,
int precision,
SQLCollationCode collation,
int length);
SQLTypeCode getSQLType() const;
SQLTypeClassCode getSQLTypeClass() const;
SQLTypeSubClassCode getSQLTypeSubClass() const;
bool getIsNullable() const;
int getScale() const;
SQLCharsetCode getCharset() const;
SQLIntervalCode getIntervalCode() const;
int getPrecision() const;
SQLCollationCode getCollation() const;
int getByteLength() const;
int getMaxCharLength() const;
// non-const methods for use at compile time
void setNullable(bool nullable);
// UDR writers can ignore these methods
int getInt(const char *row, bool &wasNull) const;
long getLong(const char *row, bool &wasNull) const;
double getDouble(const char *row, bool &wasNull) const;
time_t getTime(const char *row, bool &wasNull) const;
bool getBoolean(const char *row, bool &wasNull) const;
const char * getRaw(const char *row,
bool &wasNull,
int &byteLen) const;
bool isAvailable() const;
void setInt(int val, char *row) const;
void setLong(long val, char *row) const;
void setDouble(double val, char *row) const;
void setTime(time_t val, char *row) const;
void setString(const char *val, int stringLen, char *row) const;
void setBoolean(bool val, char *row) const;
void setNull(char *row) const;
int minBytesPerChar() const;
int convertToBinaryPrecision(int decimalPrecision) const;
void toString(std::string &s, bool longForm) const;
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
void setOffsets(int dataOffset, int indOffset, int vcOffset);
private:
// flags
enum {
TYPE_FLAG_4_BYTE_VC_LEN = 0x00000001
};
struct {
int /*SQLTypeCode */ sqlType_;
int /*bool */ nullable_;
int scale_; // scale for exact numeric,
// fraction precision for datetime/interval
int /*SQLCharsetCode */ charset_; // for character types
int /*SQLIntervalCode */ intervalCode_; // for interval types
int precision_; // decimal precision for exact numerics,
// leading interval precision for intervals
int /*SQLCollationCode */ collation_; // for character types
int length_; // for numeric (decimal precision) and character types
int dataOffset_; // offset in record for data portion
int nullIndOffset_; // offset in record for 2 or 4 byte varchar length
int vcLenIndOffset_;// offset in record for 2 byte null indicator
int flags_; // bit flags
int fillers_[4]; // for adding more fields without versioning
} d_;
// this class is used by the Trafodion compiler
friend class ::TMUDFInternalSetup;
};
/**
* @brief Describes where an output column is coming from.
*
* Points to input table and input column number that is the
* source of a column. This must only be used if the result column
* always has the exact same value as the current value of the
* corresponding input column.
*
* @see ColumnInfo::getProvenance()
* @see ColumnInfo::setProvenance()
* @see UDRInvocationInfo::addPassThruColumns()
*/
class ProvenanceInfo
{
public:
ProvenanceInfo();
ProvenanceInfo(int inputTableNum,
int inputColNum);
int getInputTableNum() const;
int getInputColumnNum() const;
bool isFromInputTable(int inputTableNum = -1) const;
private:
int inputTableNum_;
int inputColNum_;
};
/**
* @brief Describes a column in an input or output table or a parameter
*
* This describes a column or parameter value that is passed through
* the UDR interface, either as a value read from an input table, a
* value produced in an output table or a parameter.
*/
class ColumnInfo : public TMUDRSerializableObject
{
public:
/** @brief Info on whether a table-valued input or output column is used */
enum ColumnUseCode
{
UNKNOWN, ///< Column usage is not yet determined
USED, ///< For an input, it’s needed by the UDF, for an output
///< it’s needed by the SQL Engine
NOT_USED, ///< Input or output is not needed. Input will be
///< removed after the describeDataflowAndPredicates()
///< call. Output will be retained to avoid errors at
///< runtime when the UDF tries to set this column value.
NOT_PRODUCED ///< Output is not needed and will be removed after the
///< describeDataflowAndPredicates() call.
};
ColumnInfo();
ColumnInfo(const char *name,
const TypeInfo &type);
const std::string &getColName() const;
const TypeInfo &getType() const;
long getEstimatedUniqueEntries() const;
ColumnUseCode getUsage() const;
const ProvenanceInfo &getProvenance() const;
// for use during compilation
TypeInfo &getType();
void setColName(const char *name);
void setType(TypeInfo &type);
void setEstimatedUniqueEntries(long uniqueEntries);
void setUsage(ColumnUseCode usage);
void setProvenance(const ProvenanceInfo &provenance);
// Functions for debugging
void toString(std::string &s, bool longForm = false) const;
// UDR writers can ignore these methods
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
std::string name_;
TypeInfo type_;
ColumnUseCode usage_;
long estimatedUniqueEntries_;
ProvenanceInfo provenance_;
friend class ::TMUDFInternalSetup;
};
/**
* @brief A constraint on a table-valued input or output table
*
* This could be a uniqueness constraint, a cardinality constraint
* or some other constraint
*/
class ConstraintInfo : public TMUDRSerializableObject
{
public:
/** Type of a constraint */
enum ConstraintTypeCode
{
CARDINALITY, ///< Cardinality constraint
UNIQUE ///< Uniqueness constraint
};
ConstraintTypeCode getType() const;
// UDR writers can ignore these methods
virtual void toString(const TableInfo &ti, std::string &s) = 0;
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
protected:
ConstraintInfo(ConstraintTypeCode constraintType,
unsigned short version);
private:
ConstraintTypeCode constraintType_;
};
/**
* @brief A cardinality constraint
*
* Upper and/or lower bounds for the cardinality of
* a table. Note that unlike cardinality estimates, this
* is a hard constraint that must be followed by the table,
* otherwise incorrect results and errors may occur.
*/
class CardinalityConstraintInfo : public ConstraintInfo
{
public:
CardinalityConstraintInfo(long minNumRows = 0,
long maxNumRows = -1);
long getMinNumRows() const;
long getMaxNumRows() const;
// UDR writers can ignore these methods
virtual void toString(const TableInfo &ti, std::string &s);
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
long minNumRows_;
long maxNumRows_;
};
/**
* @brief A uniqueness constraint
*
* A list of columns that, together, form a unique key
*/
class UniqueConstraintInfo : public ConstraintInfo
{
public:
UniqueConstraintInfo();
int getNumUniqueColumns() const;
int getUniqueColumn(int i) const;
void addColumn(int c);
// UDR writers can ignore these methods
virtual void toString(const TableInfo &ti, std::string &s);
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
std::vector<int> uniqueColumns_;
};
/**
* @brief A predicate to be evaluated on a table
*
* These could be different kinds of predicates, like an equals
* predicate, a non-equals predicate or more complex cases.
*/
class PredicateInfo : public TMUDRSerializableObject
{
public:
/**
* @brief Info on whether a table-valued input or output column is used
*
* Note that these are not necessarily exclusive, a predicate might
* be evaluated in multiple places, although that should not be
* common and is not yet allowed.
*/
enum EvaluationCode
{
UNKNOWN_EVAL = 0, ///< Not yet determined where predicate
///< is evaluated.
EVALUATE_ON_RESULT = 0x1, ///< Predicate is evaluated on the
///< UDF result, in Trafodion code.
///< This is the default.
EVALUATE_IN_UDF = 0x2, ///< Predicate is evaluated inside the
///< code provided by the UDR writer.
EVALUATE_IN_CHILD = 0x4 ///< Predicate should be evaluated
///< in a table-valued input before
///< the data reaches the UDF.
};
/** Operator of a relational (comparison) predicate */
enum PredOperator
{
UNKNOWN_OP, ///< Operator not yet determined
EQUAL, ///< Equals predicate (col = val)
NOT_EQUAL, ///< Not equals predicate (col <> val)
LESS, ///< Less than predicate (col <)
LESS_EQUAL, ///< Less or equals predicate (col <=)
GREATER, ///< Greater predicate (col >)
GREATER_EQUAL, ///< Greater or equals predicate (col >=)
IN, ///< IN predicate (col IN)
NOT_IN ///< NOT IN predicate (col NOT IN)
};
EvaluationCode getEvaluationCode() const;
PredOperator getOperator() const;
bool isAComparisonPredicate() const;
// UDR writers can ignore these methods
PredicateInfo(TMUDRSerializableObject::TMUDRObjectType t);
void setOperator(PredOperator op);
void setEvaluationCode(EvaluationCode c);
virtual void mapColumnNumbers(const std::vector<int> &map) = 0;
virtual void toString(std::string &s,
const TableInfo &ti) const = 0;
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
int evalCode_;
PredOperator operator_;
};
/**
* @brief A comparison predicate to be evaluated on a table
*
* A predicate that compares a column value to a constant or
* another value that evaluates to a constant at runtime,
* like an SQL query parameter.
*/
class ComparisonPredicateInfo : public PredicateInfo
{
public:
int getColumnNumber() const;
bool hasAConstantValue() const;
std::string getConstValue() const;
// UDR writers can ignore these methods
ComparisonPredicateInfo();
void setColumnNumber(int columnNumber);
void setValue(const char *value);
virtual void mapColumnNumbers(const std::vector<int> &map);
virtual void toString(std::string &s,
const TableInfo &ti) const;
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
int columnNumber_;
std::string value_;
};
/**
* @brief Partitioning key of an input table or result table
*
* Describes the partitioning key of a table-valued input or
* result. When executing a UDR in parallel, if a table is
* partitioned on some columns, e.g. (a,b), this means that a rows
* with particular values for (a,b), e.g. (10, 20) will all go to
* the same parallel instance and will be seen as a contiguous
* group. This is similar to the key of a reducer in MapReduce,
* except that in this case we process a group of rows with the
* same key, not a single key and a list of values.
*/
class PartitionInfo
{
public:
/** Type of partitioning */
enum PartitionTypeCode
{
UNKNOWN, ///< Partitioning type not yet determined.
ANY, ///< No limitations on parallel execution, typical for
///< mappers, any row can be evaluated by any parallel
///< instance of the UDF.
SERIAL, ///< No partitioning is allowed, execute serially in a
///< single instance.
PARTITION, ///< Allow parallelism with partitioning key, if specified,
///< serial execution otherwise.
REPLICATE ///< Replicate the data to each parallel instance.
};
// const Functions for use by UDR writer, both at compile and at run time
PartitionInfo();
PartitionTypeCode getType() const;
int getNumEntries() const;
int getColumnNum(int i) const;
// Functions available at compile time only
void setType(PartitionTypeCode type);
void addEntry(int colNum);
void clear();
// UDR writers can ignore these methods
void mapColumnNumbers(const std::vector<int> &map);
private:
PartitionTypeCode type_;
std::vector<int> partCols_;
};
/**
* @brief Ordering of a table by some ascending or descending columns
*
* A list of columns, represented by column numbers, with an
* ascending/descending indicator for each column.
*/
class OrderInfo
{
public:
/**
* @brief Ascending/descending order of columns
*
* For outputs, the ordering of values from the first row out to the
* last. Note that this ordering applies within a parallel instance
* of the UDF at runtime, but it does not guarantee a total
* order. For example, two parallel instances may get these ordered
* values: instance 0 gets 1,3,5,7 instance 1 gets 2,4,6,8
*/
enum OrderTypeCode
{
NO_ORDER, ///< Unspecified order
ASCENDING, ///< Ascending order
DESCENDING ///< Descending order
};
// const Functions for use by UDR writer, both at compile and at run time
int getNumEntries() const;
int getColumnNum(int i) const;
OrderTypeCode getOrderType(int i) const;
// Functions available at compile time only
void addEntry(int colNum, OrderTypeCode orderType = ASCENDING);
void addEntryAt(int pos,
int colNum,
OrderTypeCode orderType = ASCENDING);
void clear();
// UDR writers can ignore these methods
void mapColumnNumbers(const std::vector<int> &map);
private:
std::vector<int> columnNumbers_;
std::vector<OrderTypeCode> orderTypes_;
};
/**
* @brief Common base class for parameter lists and row layouts
*
* Describes a list of scalars, which could be columns of a table
* or a parameter list
*/
class TupleInfo : public TMUDRSerializableObject
{
public:
// Functions for use by UDR writer, both at compile and at run time
int getNumColumns() const;
int getColNum(const char *colName) const;
int getColNum(const std::string &colName) const;
const ColumnInfo &getColumn(int colNum) const;
const ColumnInfo &getColumn(const std::string &colName) const;
const TypeInfo &getType(int colNum) const;
TypeInfo::SQLTypeClassCode getSQLTypeClass(int colNum) const;
// get values at runtime and also values of available
// constant input parameters at compile time
int getInt(int colNum) const;
int getInt(const std::string &colName) const;
long getLong(int colNum) const;
long getLong(const std::string &colName) const;
double getDouble(int colNum) const;
double getDouble(const std::string &colName) const;
std::string getString(int colNum) const;
std::string getString(const std::string &colName) const;
bool getBoolean(int colNum) const;
bool getBoolean(const std::string &colName) const;
const char * getRaw(int colNum, int &byteLen) const;
time_t getTime(int colNum) const;
bool isAvailable(int colNum) const;
void getDelimitedRow(std::string &row,
char delim='|',
bool quote = false,
char quoteSymbol = '"',
int firstColumn = 0,
int lastColumn = -1) const;
bool wasNull() const; // did getXXX() method return a NULL?
// non-const methods, used during runtime only
void setInt(int colNum, int val) const;
void setLong(int colNum, long val) const;
void setDouble(int colNum, double val) const;
void setString(int colNum, const char *val) const;
void setString(int colNum, const char *val, int stringLen) const;
void setString(int colNum, const std::string &val) const;
void setTime(int colNum, time_t val) const;
void setBoolean(int colNum, bool val) const;
const char * setFromDelimitedRow(const char *row,
char delim='|',
bool quote = false,
char quoteSymbol = '"',
int firstColumnToSet = 0,
int lastColumnToSet = -1,
int numDelimColsToSkip = 0) const;
void setNull(int colNum) const;
// non-const methods, used during compile time only
ColumnInfo &getColumn(int colNum);
ColumnInfo &getColumn(const std::string &colName);
void addColumn(const ColumnInfo &column);
// for convenient adding of columns of a common type
void addIntColumn(const char *colName, bool isNullable = false);
void addLongColumn(const char *colName, bool isNullable = false);
void addDoubleColumn(const char *colName, bool isNullable = false);
void addCharColumn(
const char *colName,
int length,
bool isNullable = false,
TypeInfo::SQLCharsetCode charset = TypeInfo::CHARSET_UTF8,
TypeInfo::SQLCollationCode collation = TypeInfo::SYSTEM_COLLATION);
void addVarCharColumn(
const char *colName,
int length,
bool isNullable = false,
TypeInfo::SQLCharsetCode charset = TypeInfo::CHARSET_UTF8,
TypeInfo::SQLCollationCode collation = TypeInfo::SYSTEM_COLLATION);
void addColumns(const std::vector<ColumnInfo *> &columns);
void addColumnAt(const ColumnInfo &column, int position);
void deleteColumn(int i);
void deleteColumn(const std::string &name);
// useful for cost estimation
int getRecordLength() const;
// Functions for debugging
void print();
// UDR writers can ignore these methods
TupleInfo(TMUDRObjectType objType, int version);
~TupleInfo();
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
char *getRowPtr() const;
protected:
void setRecordLength(int len);
void setRowPtr(char *ptr);
// this object owns all the ColumnInfo objects
// contained in its data members, and the destructor will delete them,
// but this object does NOT own the buffer pointed to by rowPtr_
std::vector<ColumnInfo *> columns_;
int recordLength_;
char * rowPtr_;
bool wasNull_;
// this class is used by the Trafodion compiler
friend class ::TMUDFInternalSetup;
friend class ::LmRoutineCppObj;
};
/**
* @brief Describes a table-valued input or a table-valued output
*/
class TableInfo : public TupleInfo
{
public:
// Functions for use by UDR writer, both at compile and at run time
long getEstimatedNumRows() const;
long getEstimatedNumPartitions() const;
const PartitionInfo &getQueryPartitioning() const;
const OrderInfo &getQueryOrdering() const;
bool isStream() const;
int getNumConstraints() const;
const ConstraintInfo &getConstraint(int i) const;
// non-const methods, used during compile time only
void setEstimatedNumRows(long rows);
void addCardinalityConstraint(const CardinalityConstraintInfo &constraint);
void addUniquenessConstraint(const UniqueConstraintInfo &constraint);
void setIsStream(bool stream);
// Functions for debugging
void print();
// UDR writers can ignore these methods
TableInfo();
~TableInfo();
inline static unsigned short getCurrentVersion() { return 1; }
PartitionInfo &getQueryPartitioning();
OrderInfo &getQueryOrdering();
void setQueryPartitioning(const PartitionInfo &partInfo);
void setQueryOrdering(const OrderInfo &orderInfo);
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
// this object owns all the ConstraintInfo objects
// contained in its data members, and the destructor will delete them
long estimatedNumRows_;
long estimatedNumPartitions_;
PartitionInfo queryPartitioning_;
OrderInfo queryOrdering_;
std::vector<ConstraintInfo *> constraints_;
// this class is used by the Trafodion compiler
friend class ::TMUDFInternalSetup;
};
/**
* @brief Describes the parameters of a UDR.
*
* This method currently has no methods relevant to the UDR
* writer, but the base class, TupleInfo, has a variety of methods.
*
* @see TupleInfo
*/
class ParameterListInfo : public TupleInfo
{
public:
ParameterListInfo();
virtual ~ParameterListInfo();
// UDR writers can ignore these methods
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
};
/**
* @brief Compile time data owned by the UDR writer
*
* When attached to a UDRInvocationInfo object, keeps context
* between compiler interface calls for this object. This class
* can also be attached to a UDRPlanInfo object, to keep state
* between plan alternatives for a UDR invocation. The
* info is NOT passed to the run time methods, use
* UDRPlanInfo::addPlanData() for that.
*/
class UDRWriterCompileTimeData
{
public:
UDRWriterCompileTimeData();
virtual ~UDRWriterCompileTimeData();
// Functions for debugging
virtual void print();
};
/**
* @brief Describes an invocation of a UDR
*
* This combines the description of the UDR, its names and
* properties with the parameters, input and output table layouts
* and other information. An object of this class is passed to
* most methods defined by the UDR writer. It can be used to
* get input and parameter data and to set values of table-valued
* output columns.
*/
class UDRInvocationInfo : public TMUDRSerializableObject
{
public:
/**
* @brief Type of a TMUDF: Generic, mapper or reducer.
*/
enum FuncType // The type of this UDF.
{
GENERIC, ///< The Trafodion compiler will make only the
///< most conservative assumptions about this type of UDF.
MAPPER, ///< A UDF that behaves like a mapper. A mapper does not
///< carry any state between rows it reads from its
///< table-valued inputs. It produces zero or more output
///< rows per input row. Because no state is kept between
///< rows, the Trafodion compiler can automatically
///< parallelize execution and push predicates down to
///< the table-valued inputs.
REDUCER, ///< A reducer requires the data to be partitioned on
///< a set of columns. The UDF does not carry any state
///< between groups of rows with the same partition column
///< values, but it may carry state within such groups.
///< This allows the compiler to parallelize execution and
///< to push predicates on the partitioning column(s) down
///< to table-valued inputs.
REDUCER_NC ///< Same as REDUCER, except that in this case the
///< UDF does not require the rows belonging to a key
///< to be grouped together, they can be non-contiguous
///< (NC). This can avoid a costly sort of the input
///< table in cases where a highly reducing UDF can keep
///< a table of all the keys in memory.
};
/**
* Type of SQL access allowed in this routine
*/
enum SQLAccessType
{
CONTAINS_NO_SQL,
READS_SQL,
MODIFIES_SQL
};
/**
* Type of transaction that is required, if any
*/
enum SQLTransactionType
{
REQUIRES_NO_TRANSACTION,
REQUIRES_SQL_TRANSACTION
};
/**
* Effective user ids for determining privileges
*
* This is meaningful only for UDRs that perform SQL
* operations, using the default connection.
*/
enum SQLRightsType
{
INVOKERS_RIGHTS,
DEFINERS_RIGHTS
};
/**
* Indicates whether this UDR is trusted or not
*/
enum IsolationType
{
ISOLATED,
TRUSTED
};
/**
* @brief call phase for the UDR interface
*
* This is of limited interest for UDR writers and mostly
* used internally to ensure method calls are not done at
* the wrong time.
*/
enum CallPhase
{
UNKNOWN_CALL_PHASE = 0,
// some pseudo-phases for the initial setup,
// not involving a UDRInvocationInfo object
DEBUG_LOOP_CALL = 4,
GET_ROUTINE_CALL = 6,
// following are the actual call phases
COMPILER_INITIAL_CALL = 10,
COMPILER_DATAFLOW_CALL = 20,
COMPILER_CONSTRAINTS_CALL = 30,
COMPILER_STATISTICS_CALL = 40,
COMPILER_DOP_CALL = 50,
COMPILER_PLAN_CALL = 60,
COMPILER_COMPLETION_CALL = 70,
RUNTIME_WORK_CALL = 110
};
/**
* @brief values used for the UDR_DEBUG_FLAGS CQD
*
* use cqd UDR_DEBUG_FLAGS 'num' in SQL to set these, add up
* the flags (in decimal) that you want to set. See
* https://cwiki.apache.org/confluence/display/TRAFODION/Tutorial%3A+The+object-oriented+UDF+interface#Tutorial:Theobject-orientedUDFinterface-DebuggingUDFcode
* for details.
*/
enum DebugFlags
{
DEBUG_INITIAL_RUN_TIME_LOOP_ONE = 0x00000001, ///< 1
DEBUG_INITIAL_RUN_TIME_LOOP_ALL = 0x00000002, ///< 2
DEBUG_INITIAL_COMPILE_TIME_LOOP = 0x00000004, ///< 4
DEBUG_LOAD_MSG_LOOP = 0x00000008, ///< 8
TRACE_ROWS = 0x00000010, ///< 16
PRINT_INVOCATION_INFO_INITIAL = 0x00000020, ///< 32
PRINT_INVOCATION_INFO_END_COMPILE = 0x00000040, ///< 64
PRINT_INVOCATION_INFO_AT_RUN_TIME = 0x00000080, ///< 128
VALIDATE_WALLS = 0x00000100 ///< 256
};
// there are no public constructors for this class
// const Functions for use by UDR writer, both at compile and at run time
const std::string &getUDRName() const;
int getNumTableInputs() const;
const TableInfo &in(int childNum = 0) const;
const TableInfo &out() const;
CallPhase getCallPhase() const;
const std::string &getCurrentUser() const;
const std::string &getSessionUser() const;
const std::string &getCurrentRole() const;
SQLAccessType getSQLAccessType() const;
SQLTransactionType getSQLTransactionType() const;
SQLRightsType getSQLRights() const;
IsolationType getIsolationType() const;
bool isCompileTime() const;
bool isRunTime() const;
int getDebugFlags() const;
FuncType getFuncType() const;
const ParameterListInfo &getFormalParameters() const;
const ParameterListInfo &par() const; // actual parameters
int getNumPredicates() const;
const PredicateInfo &getPredicate(int i) const;
bool isAComparisonPredicate(int i) const;
const ComparisonPredicateInfo &getComparisonPredicate(int i) const;
// Functions available at compile time only
// use the next six only from describeParamsAndColumns()
TableInfo &out();
void addFormalParameter(const ColumnInfo &param);
void setFuncType(FuncType type);
void addPassThruColumns(int inputTableNum = 0,
int startInputColNum = 0,
int endInputColNum = -1);
void setChildPartitioning(int inputTableNum,
const PartitionInfo &partInfo);
void setChildOrdering(int inputTableNum,
const OrderInfo &orderInfo);
// use only from describeDataflowAndPredicates()
void setChildColumnUsage(int inputTableNum,
int inputColumnNum,
ColumnInfo::ColumnUseCode usage);
void setUnusedPassthruColumns();
void setPredicateEvaluationCode(int predicateNum,
PredicateInfo::EvaluationCode c);
void pushPredicatesOnPassthruColumns(int startPredNum = 0,
int lastPredNum = -1);
// use only from describeConstraints()
void propagateConstraintsFor1To1UDFs(bool exactlyOneRowPerInput);
// use anytime during compilation
UDRWriterCompileTimeData *getUDRWriterCompileTimeData();
void setUDRWriterCompileTimeData(UDRWriterCompileTimeData *compileTimeData);
// Functions available at run-time only
void copyPassThruData(int inputTableNum = 0,
int startInputColNum = 0,
int endInputColNum = -1);
const std::string &getQueryId() const;
int getNumParallelInstances() const;
int getMyInstanceNum() const; // 0 ... getNumInstances()-1
// Functions for debugging
void print();
// UDR writers can ignore these methods
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
void serializeObj(Bytes outputBuffer, int outputBufferLength);
void deserializeObj(ConstBytes inputBuffer, int inputBufferLength);
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
static const char *callPhaseToString(CallPhase c);
private:
UDRInvocationInfo();
~UDRInvocationInfo();
ParameterListInfo &nonConstFormalParameters();
ParameterListInfo &nonConstActualParameters();
void validateCallPhase(CallPhase start,
CallPhase end,
const char *callee) const;
void setQueryId(const char *qid);
void setTotalNumInstances(int i);
void setMyInstanceNum(int i);
static const int MAX_INPUT_TABLES = 2;
std::string name_;
int numTableInputs_;
CallPhase callPhase_;
std::string currentUser_;
std::string sessionUser_;
std::string currentRole_;
std::string queryId_;
SQLAccessType sqlAccessType_;
SQLTransactionType sqlTransactionType_;
SQLRightsType sqlRights_;
IsolationType isolationType_;
TableInfo inputTableInfo_[MAX_INPUT_TABLES];
TableInfo outputTableInfo_;
int debugFlags_;
FuncType funcType_;
ParameterListInfo formalParameterInfo_;
ParameterListInfo actualParameterInfo_;
std::vector<PredicateInfo *> predicates_;
UDRWriterCompileTimeData *udrWriterCompileTimeData_;
int totalNumInstances_;
int myInstanceNum_;
friend class UDRPlanInfo;
// these classes are used internally by Trafodion
friend class ::TMUDFInternalSetup;
friend class ::SPInfo;
friend class ::LmLanguageManagerC;
friend class ::LmLanguageManagerJava;
friend class ::LmRoutineCppObj;
};
/**
* @brief Describes the query plan used for a UDR invocation
*
* Objects of this type are used together with UDRInvocationInfo
* objects and they contain additional info on plan-related
* such as the chosen partitioning and ordering.
*/
class UDRPlanInfo : public TMUDRSerializableObject
{
public:
/** @brief Special degrees of parallelism.
*
* Values that can be used in the setDesiredDegreeOfParallelism()
* method, in addition to positive numbers for the degree of
* parallelism (DoP).
*/
enum SpecialDegreeOfParallelism
{
ANY_DEGREE_OF_PARALLELISM = 0, ///< Optimizer decides DoP
DEFAULT_DEGREE_OF_PARALLELISM = -1, ///< Optimizer decides DoP based
///< on dataflow heuristics.
MAX_DEGREE_OF_PARALLELISM = -2, ///< Execute the UDF with the
///< largest degree of parallelism
///< allowed.
ONE_INSTANCE_PER_NODE = -3 ///< Execute one instance of the
///< on every Trafodion node.
///< Used internally for
///< maintenance UDFs.
};
// Functions for use by UDR writer, both at compile and at run time
int getPlanNum() const;
long getCostPerRow() const;
int getDesiredDegreeOfParallelism() const;
// Functions available at compile time only
// call this from describePlanProperties() or earlier
void setCostPerRow(long nanoseconds);
// call this from describeDesiredDegreeOfParallelism() or earlier
void setDesiredDegreeOfParallelism(int dop);
UDRWriterCompileTimeData *getUDRWriterCompileTimeData();
void setUDRWriterCompileTimeData(UDRWriterCompileTimeData *compileTimeData);
// call this from completeDescription() or earlier
void addPlanData(const char *planData,
int planDataLength);
const char *getPlanData(int &planDataLength);
// Functions for debugging
void print();
// UDR writers can ignore these methods
inline static unsigned short getCurrentVersion() { return 1; }
virtual int serializedLength();
void serializeObj(Bytes outputBuffer, int outputBufferLength);
void deserializeObj(ConstBytes inputBuffer, int inputBufferLength);
virtual int serialize(Bytes &outputBuffer,
int &outputBufferLength);
virtual int deserialize(ConstBytes &inputBuffer,
int &inputBufferLength);
private:
UDRPlanInfo(UDRInvocationInfo *invocationInfo, int planNum);
~UDRPlanInfo();
UDRInvocationInfo *invocationInfo_;
int planNum_;
long costPerRow_;
int degreeOfParallelism_;
UDRWriterCompileTimeData *udrWriterCompileTimeData_;
const char *planData_;
int planDataLength_;
// class is used internally by Trafodion
friend class ::TMUDFInternalSetup;
friend class ::SPInfo;
friend class ::LmLanguageManagerC;
friend class ::LmRoutineCppObj;
};
/**
* @brief This class represents the code associated with a UDR.
*
* UDR writers can create a derived class and implement these methods
* for their specific UDR. The base class also has default methods
* for all but the runtime call. See
* https://cwiki.apache.org/confluence/display/TRAFODION/Tutorial%3A+The+object-oriented+UDF+interface
* for examples.
*
* To use this interface, the UDR writer must provide a function
* of type CreateInterfaceObjectFunc with a name that's the UDR
* external name, and it must have "C" linkage. Example, assuming
* the external name of the UDF is MYUDF:
*
* @code
* // define a class that is derived from UDR
* class MyUDFInterface : public UDR
* {
* // Override any virtual methods where the UDF author would
* // like to change the default behavior. It is fine to add
* // other methods and data members, just make sure to free
* // up all resources in the destructor.
* ...
* };
* // define a "factory" function to return an object of this class
* extern "C"
* SQLUDR_LIBFUNC UDR * MYUDF()
* {
* return new MyUDFInterface;
* }
* @endcode
*
* @arg If the describeParamsAndColumns() interface is not used, all
* parameters and result table columns must be declared in the
* CREATE TABLE MAPPING FUNCTION DDL.
* @arg When using the describeParamsAndColumns() interface, additional
* parameters and all output columns can be defined at compile time.
* @arg A UDR writer can decide to override none, some or all of
* the virtual methods in the compiler interface. The run-time
* interface, processData(), must always be provided.
* @arg See file sqludr.cpp for the default implementation of these
* methods.
* @arg When overriding methods, the UDR writer has the option to
* call the default method to do part of the work, and then to
* implement additional logic.
* @arg Multiple UDRs could share the same subclass of UDR.
* The UDR name is passed in UDRInvocationInfo, so the logic can
* depend on the name.
* @arg A single query may invoke the same UDR more than once. A
* different UDRInvocationInfo object will be passed for each
* such invocation.
* @arg The UDR object or the object of its derived class
* may be reused for multiple queries, so its life time can
* exceed that of a UDRInvocationInfo object.
* @arg Different instances of UDR (or derived class)
* objects will be created in the processes that compile and
* execute a query.
* @arg Based on the previous three bullets, UDR writers should not
* store state that relates to a UDR invocation in a UDR
* (or derived) object. There are special classes to do that.
* It is ok to use the UDR derived class to store
* resources that are shared between UDR invocations, such as
* connections to server processes etc. These need to be cleaned
* up by overloading the destructor.
* @arg The optimizer may try different execution plans for a UDR
* invocation, e.g. with different partitioning and ordering
* of input and/or output data. These alternative plans share
* the same UDRInvocationInfo object but they will use different
* UDRPlanInfo objects.
*/
class UDR
{
public:
UDR();
virtual ~UDR();
// compile time interface for UDRs
virtual void describeParamsAndColumns(UDRInvocationInfo &info);
virtual void describeDataflowAndPredicates(UDRInvocationInfo &info);
virtual void describeConstraints(UDRInvocationInfo &info);
virtual void describeStatistics(UDRInvocationInfo &info);
virtual void describeDesiredDegreeOfParallelism(UDRInvocationInfo &info,
UDRPlanInfo &plan);
virtual void describePlanProperties(UDRInvocationInfo &info,
UDRPlanInfo &plan);
virtual void completeDescription(UDRInvocationInfo &info,
UDRPlanInfo &plan);
// run time interface for TMUDFs and scalar UDFs (once supported)
virtual void processData(UDRInvocationInfo &info,
UDRPlanInfo &plan);
// methods to be called from the run time interface for UDRs:
// read a row from an input table
bool getNextRow(UDRInvocationInfo &info, int tableIndex = 0);
// produce a result row
void emitRow(UDRInvocationInfo &info);
// methods for debugging
virtual void debugLoop();
// methods for versioning of this interface
inline static unsigned short getCurrentVersion() { return 1; }
virtual int getFeaturesSupportedByUDF();
friend class ::LmRoutineCppObj;
private:
SQLUDR_GetNextRow getNextRowPtr_;
SQLUDR_EmitRow emitRowPtr_;
};
/**
* @brief Function pointer type for the factory method
*/
typedef UDR * (*CreateInterfaceObjectFunc) ();
} // end of namespace tmudr
// end of C++ interface for UDRs
#endif
// SQLUDR_H
#endif