/* ----------------------------------------------------------------------- *//**
 *
 * @file SystemInformation.hpp
 *
 *//* ----------------------------------------------------------------------- */

#ifndef MADLIB_POSTGRES_SYSTEMINFORMATION_PROTO_HPP
#define MADLIB_POSTGRES_SYSTEMINFORMATION_PROTO_HPP

#include "UDF_proto.hpp" // We need UDF::Pointer

namespace madlib {

namespace dbconnector {

namespace postgres {

/**
 * @brief Cached information about PostgreSQL types
 *
 * For explanations, see struct FormData_pg_type defined in pg_type.h
 * and struct TypeCacheEntry defined in typcache.h.
 */
struct TypeInformation {
    /**
     * OID and hash key. Must be the first element.
     */
    Oid oid;

    /**
     * Type name
     */
    char name[NAMEDATALEN];

	/**
	 * For a fixed-size type, typlen is the number of bytes PostgreSQL uses to
	 * represent a value of this type, e.g., 4 for an int4.	But for a
	 * variable-length type, typlen is negative.  -1 indicates a "varlena" type
     * (one that has a length word), -2 indicates a null-terminated C string.
	 */
	int16_t len;

    /**
     * typbyval determines whether internal Postgres routines pass a value of
	 * this type by value or by reference.
     */
	bool byval;

    /**
     * pg_type.h defines the following types:
     * <tt>TYPTYPE_{BASE|COMPOSITE|DOMAIN|ENUM|PSEUDO}</tt>
     */
    char type;

    /**
     * Tuple descriptor if it's a composite type (row type).  NULL if not
     * composite. This is not a reference-counted TupleDesc and we rely
     * on the PostgreSQL garbage collection for cleanup.
     */
    TupleDesc tupdesc;

    TupleDesc getTupleDesc(int32_t inTypMod = -1);
    bool isCompositeType();
    const char* getName();
    bool isByValue();
    int16_t getLen();
    char getType();
};

/**
 * @brief Cached information about PostgreSQL functions
 *
 * For explanations, see struct FmgrInfo in fmgr.h,
 * struct FuncCallContext in funcapi.h, enum TypeFuncClass in funcapi.h,
 * and struct FormData_pg_proc in pg_proc.h.
 */
struct FunctionInformation {
    /**
     * OID and hash key. Must be the first element.
     */
    Oid oid;

    /**
     * Function pointer to C++ function. If this is non-null, the function
     * is known to be implemented on top of the C++ abstraction layer. NULL
     * if not or unknown. If non-NULL, we this function pointer will be
     * called directly, thus circumventing any detour through the backend.
     */
    UDF::Pointer cxx_func;

    /**
     * Holds system-catalog information that must be looked up before a
     * function can be called through fmgr. We store it here, because the
     * information can be reused for multiple function calls.
     * An uninitialized flinfo is indicated by <tt>flinfo.fn_oid</tt> not
     * being equal to \c oid.
     *
     * FIXME: Currently, no expression parse tree is stored. In fact, there
     * is none, and we would have to artificially generate a default
     * expression parse tree. This implies that function that are called
     * from C++ functions currently do not support the following features:
     * - Polymorphism
     * - Anonymous return tuples
     */
    FmgrInfo flinfo;

    /**
     * funcapi.h defines the following classes:
     * <tt>TYPEFUNC_{SCALAR|COMPOSITE|RECORD|OTHER}</tt>
     */
    TypeFuncClass funcclass;


    /**
     * Number of input arguments. Note that short is the data type used in
     * <tt>struct FunctionCallInfoData</tt>.
     */
    uint16_t nargs;

    /**
     * Array (of length nargs) containing the argument type IDs (excludes
     * OUT parameters).
     */
    Oid *argtypes;

    /**
     * True if we the function may have different return types.
     * False if we the function will always have the same return type.
     */
    bool polymorphic;

    /**
     * True if the function always returns null whenever any of its
     * arguments are null. If this parameter is specified, the function is
     * not executed when there are null arguments.
     */
    bool isstrict;

    /**
     * True if function is to be executed with the privileges of the user
     * that created it. The attribute is called SECURITY DEFINER in
     * PostgreSQL.
     */
    bool secdef;

    /**
     * OID of result type
     */
    Oid rettype;

    /**
     * If rettype == RECORDOID but the result type is composite (but not
     * polymorphic), then this will contain a tuple descriptor. NULL
     * otherwise. This is not a reference-counted TupleDesc and we rely
     * on the PostgreSQL garbage collection for cleanup.
     */
    TupleDesc tupdesc;

    /**
     * Backpointer to SystemInformation
     */
    SystemInformation* mSysInfo;

    Oid getArgumentType(uint16_t inArgID, FmgrInfo* inFmgrInfo = NULL);
    Oid getReturnType(FunctionCallInfo fcinfo);
    TupleDesc getReturnTupleDesc(FunctionCallInfo fcinfo);
    FmgrInfo* getFuncMgrInfo();
    const char* getFullName();
};

/**
 * @brief Cached information about the PostgreSQL system catalog
 *
 * In order to guarantee type-safety through reflection/type-introspection, the
 * C++ AL has to call many PostgreSQL functions that are tagged as expensive due
 * to lookups in the type cache or even in the system catalog. We therefore wrap
 * all catalog lookups in this class and store the results in our own cache.
 * There is one cache per entry point into the C++ AL, i.e., one per function
 * that is called from the backend. If a UDF based on this AL calls another such
 * UDF, the same cache is reused.
 * Each cache is stored in the \c fn_extra field of struct \c FmgrInfo (or in
 * the \c user_fctx field of struct \c FuncCallContext). As such, the cache only
 * lives till the end of the current query (see
 * <http://www.postgresql.org/docs/current/static/plhandler.html>).
 *
 * @note
 *     In order to not leave defined C++ behavior, this must be a plain-old data
 *     (POD) for the following reason: We store a pointer to our cached
 *     information in the fn_extra field of struct FmgrInfo (or in
 *     the user_fctx field of struct FuncCallContext). We cannot do any
 *     cleanup but instead rely on the PostgreSQL garbage collector.
 */
struct SystemInformation {
    /**
     * OID of first C++ AL function in the current execution stack.
     */
    Oid entryFuncOID;

    /**
     * The memory context used for the hash tables.
     */
    MemoryContext cacheContext;

    /**
     * Collation for function(s) to use. This will be set to fncollation
     * of struct FunctionCallInfoData if the entry-function call (i.e., the
     * first C++ AL function call in the current execution stack).
     * Note: Collation support has been added to PostgreSQL with commit
     * d64713df by Tom Lane <tgl@sss.pgh.pa.us>
     * on Tue Apr 12 2011 23:19:24 UTC. First release: PG9.1. For version, prior
     * to this, collationOID will be InvalidOid.
     */
    Oid collationOID;

    /**
     * Hash table containing information about all accessed types
     */
    HTAB *types;

    /**
     * Hash table containing information about all accessed functions
     * (starting from the function called by the backend).
     */
    HTAB *functions;

    /**
     * As we will put the SystemInformation instance to the pointer
     * static_cast<FuncCallContext*>(inFmgrInfo->fn_extra)->user_fctx
     * (retset == 1) or inFmgrInfo->fn_extra (retset == -1), we provide this
     * pointer for the users to put their own context to this pointer.
     */
    void *user_fctx;

    static SystemInformation* get(FunctionCallInfo fcinfo);
    TypeInformation* typeInformation(Oid inTypeID);
    FunctionInformation* functionInformation(Oid inFuncID);
};

} // namespace postgres

} // namespace dbconnector

} // namespace madlib

#endif // defined(MADLIB_POSTGRES_SYSTEMINFORMATION_PROTO_HPP)
