diff options
Diffstat (limited to 'src/include/fmgr.h')
-rw-r--r-- | src/include/fmgr.h | 84 |
1 files changed, 60 insertions, 24 deletions
diff --git a/src/include/fmgr.h b/src/include/fmgr.h index 0491e2e1d1..cfb7b7774d 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -8,7 +8,7 @@ * or call fmgr-callable functions. * * - * Portions Copyright (c) 1996-2016, PostgreSQL Global Development Group + * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * src/include/fmgr.h @@ -49,6 +49,9 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo); * arguments, rather than about the function itself. But it's convenient * to store it here rather than in FunctionCallInfoData, where it might more * logically belong. + * + * fn_extra is available for use by the called function; all other fields + * should be treated as read-only after the struct is created. */ typedef struct FmgrInfo { @@ -65,6 +68,11 @@ typedef struct FmgrInfo /* * This struct is the data actually passed to an fmgr-called function. + * + * The called function is expected to set isnull, and possibly resultinfo or + * fields in whatever resultinfo points to. It should not change any other + * fields. (In particular, scribbling on the argument arrays is a bad idea, + * since some callers assume they can re-call with the same arguments.) */ typedef struct FunctionCallInfoData { @@ -178,11 +186,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, * The resulting datum can be accessed using VARSIZE_ANY() and VARDATA_ANY() * (beware of multiple evaluations in those macros!) * - * WARNING: It is only safe to use pg_detoast_datum_packed() and - * VARDATA_ANY() if you really don't care about the alignment. Either because - * you're working with something like text where the alignment doesn't matter - * or because you're not going to access its constituent parts and just use - * things like memcpy on it anyways. + * In consumers oblivious to data alignment, call PG_DETOAST_DATUM_PACKED(), + * VARDATA_ANY(), VARSIZE_ANY() and VARSIZE_ANY_EXHDR(). Elsewhere, call + * PG_DETOAST_DATUM(), VARDATA() and VARSIZE(). Directly fetching an int16, + * int32 or wider field in the struct representing the datum layout requires + * aligned data. memcpy() is alignment-oblivious, as are most operations on + * datatypes, such as text, whose layout struct contains only char fields. * * Note: it'd be nice if these could be macros, but I see no way to do that * without evaluating the arguments multiple times, which is NOT acceptable. @@ -243,13 +252,9 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); /* and this if you can handle 1-byte-header datums: */ #define PG_GETARG_VARLENA_PP(n) PG_DETOAST_DATUM_PACKED(PG_GETARG_DATUM(n)) /* DatumGetFoo macros for varlena types will typically look like this: */ -#define DatumGetByteaP(X) ((bytea *) PG_DETOAST_DATUM(X)) #define DatumGetByteaPP(X) ((bytea *) PG_DETOAST_DATUM_PACKED(X)) -#define DatumGetTextP(X) ((text *) PG_DETOAST_DATUM(X)) #define DatumGetTextPP(X) ((text *) PG_DETOAST_DATUM_PACKED(X)) -#define DatumGetBpCharP(X) ((BpChar *) PG_DETOAST_DATUM(X)) #define DatumGetBpCharPP(X) ((BpChar *) PG_DETOAST_DATUM_PACKED(X)) -#define DatumGetVarCharP(X) ((VarChar *) PG_DETOAST_DATUM(X)) #define DatumGetVarCharPP(X) ((VarChar *) PG_DETOAST_DATUM_PACKED(X)) #define DatumGetHeapTupleHeader(X) ((HeapTupleHeader) PG_DETOAST_DATUM(X)) /* And we also offer variants that return an OK-to-write copy */ @@ -264,13 +269,9 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); #define DatumGetBpCharPSlice(X,m,n) ((BpChar *) PG_DETOAST_DATUM_SLICE(X,m,n)) #define DatumGetVarCharPSlice(X,m,n) ((VarChar *) PG_DETOAST_DATUM_SLICE(X,m,n)) /* GETARG macros for varlena types will typically look like this: */ -#define PG_GETARG_BYTEA_P(n) DatumGetByteaP(PG_GETARG_DATUM(n)) #define PG_GETARG_BYTEA_PP(n) DatumGetByteaPP(PG_GETARG_DATUM(n)) -#define PG_GETARG_TEXT_P(n) DatumGetTextP(PG_GETARG_DATUM(n)) #define PG_GETARG_TEXT_PP(n) DatumGetTextPP(PG_GETARG_DATUM(n)) -#define PG_GETARG_BPCHAR_P(n) DatumGetBpCharP(PG_GETARG_DATUM(n)) #define PG_GETARG_BPCHAR_PP(n) DatumGetBpCharPP(PG_GETARG_DATUM(n)) -#define PG_GETARG_VARCHAR_P(n) DatumGetVarCharP(PG_GETARG_DATUM(n)) #define PG_GETARG_VARCHAR_PP(n) DatumGetVarCharPP(PG_GETARG_DATUM(n)) #define PG_GETARG_HEAPTUPLEHEADER(n) DatumGetHeapTupleHeader(PG_GETARG_DATUM(n)) /* And we also offer variants that return an OK-to-write copy */ @@ -284,6 +285,21 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); #define PG_GETARG_TEXT_P_SLICE(n,a,b) DatumGetTextPSlice(PG_GETARG_DATUM(n),a,b) #define PG_GETARG_BPCHAR_P_SLICE(n,a,b) DatumGetBpCharPSlice(PG_GETARG_DATUM(n),a,b) #define PG_GETARG_VARCHAR_P_SLICE(n,a,b) DatumGetVarCharPSlice(PG_GETARG_DATUM(n),a,b) +/* + * Obsolescent variants that guarantee INT alignment for the return value. + * Few operations on these particular types need alignment, mainly operations + * that cast the VARDATA pointer to a type like int16[]. Most code should use + * the ...PP(X) counterpart. Nonetheless, these appear frequently in code + * predating the PostgreSQL 8.3 introduction of the ...PP(X) variants. + */ +#define DatumGetByteaP(X) ((bytea *) PG_DETOAST_DATUM(X)) +#define DatumGetTextP(X) ((text *) PG_DETOAST_DATUM(X)) +#define DatumGetBpCharP(X) ((BpChar *) PG_DETOAST_DATUM(X)) +#define DatumGetVarCharP(X) ((VarChar *) PG_DETOAST_DATUM(X)) +#define PG_GETARG_BYTEA_P(n) DatumGetByteaP(PG_GETARG_DATUM(n)) +#define PG_GETARG_TEXT_P(n) DatumGetTextP(PG_GETARG_DATUM(n)) +#define PG_GETARG_BPCHAR_P(n) DatumGetBpCharP(PG_GETARG_DATUM(n)) +#define PG_GETARG_VARCHAR_P(n) DatumGetVarCharP(PG_GETARG_DATUM(n)) /* To return a NULL do this: */ #define PG_RETURN_NULL() \ @@ -320,10 +336,10 @@ extern struct varlena *pg_detoast_datum_packed(struct varlena * datum); /*------------------------------------------------------------------------- * Support for detecting call convention of dynamically-loaded functions * - * Dynamically loaded functions may use either the version-1 ("new style") - * or version-0 ("old style") calling convention. Version 1 is the call - * convention defined in this header file; version 0 is the old "plain C" - * convention. A version-1 function must be accompanied by the macro call + * Dynamically loaded functions currently can only use the version-1 ("new + * style") calling convention. Version-0 ("old style") is not supported + * anymore. Version 1 is the call convention defined in this header file, and + * must be accompanied by the macro call * * PG_FUNCTION_INFO_V1(function_name); * @@ -344,11 +360,18 @@ typedef const Pg_finfo_record *(*PGFInfoFunction) (void); /* * Macro to build an info function associated with the given function name. - * Win32 loadable functions usually link with 'dlltool --export-all', but it - * doesn't hurt to add PGDLLIMPORT in case they don't. + * + * As a convenience, also provide an "extern" declaration for the given + * function name, so that writers of C functions need not write that too. + * + * On Windows, the function and info function must be exported. Our normal + * build processes take care of that via .DEF files or --export-all-symbols. + * Module authors using a different build process might need to manually + * declare the function PGDLLEXPORT. We do that automatically here for the + * info function, since authors shouldn't need to be explicitly aware of it. */ #define PG_FUNCTION_INFO_V1(funcname) \ -Datum funcname(PG_FUNCTION_ARGS); \ +extern Datum funcname(PG_FUNCTION_ARGS); \ extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \ const Pg_finfo_record * \ CppConcat(pg_finfo_,funcname) (void) \ @@ -468,6 +491,19 @@ extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation, Datum arg6, Datum arg7, Datum arg8, Datum arg9); +/* + * These functions work like the DirectFunctionCall functions except that + * they use the flinfo parameter to initialise the fcinfo for the call. + * It's recommended that the callee only use the fn_extra and fn_mcxt + * fields, as other fields will typically describe the calling function + * not the callee. Conversely, the calling function should not have + * used fn_extra, unless its use is known to be compatible with the callee's. + */ +extern Datum CallerFInfoFunctionCall1(PGFunction func, FmgrInfo *flinfo, + Oid collation, Datum arg1); +extern Datum CallerFInfoFunctionCall2(PGFunction func, FmgrInfo *flinfo, + Oid collation, Datum arg1, Datum arg2); + /* These are for invocation of a previously-looked-up function with a * directly-computed parameter list. Note that neither arguments nor result * are allowed to be NULL. @@ -621,7 +657,7 @@ extern bytea *OidSendFunctionCall(Oid functionId, Datum val); /* * Routines in fmgr.c */ -extern const Pg_finfo_record *fetch_finfo_record(void *filehandle, char *funcname); +extern const Pg_finfo_record *fetch_finfo_record(void *filehandle, const char *funcname); extern void clear_external_function_hash(void *filehandle); extern Oid fmgr_internal_function(const char *proname); extern Oid get_fn_expr_rettype(FmgrInfo *flinfo); @@ -637,9 +673,9 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid); */ extern char *Dynamic_library_path; -extern PGFunction load_external_function(char *filename, char *funcname, +extern PGFunction load_external_function(const char *filename, const char *funcname, bool signalNotFound, void **filehandle); -extern PGFunction lookup_external_function(void *filehandle, char *funcname); +extern PGFunction lookup_external_function(void *filehandle, const char *funcname); extern void load_file(const char *filename, bool restricted); extern void **find_rendezvous_variable(const char *varName); extern Size EstimateLibraryStateSpace(void); |