#include "postgres.h" #include "storage/lwlock.h" #include "storage/shmem.h" #include "utils/guc.h" #if PG_VERSION_NUM >= 160000 #include "utils/guc_hooks.h" #else #include "commands/variable.h" #endif #include "orafce.h" #include "builtins.h" #include "pipe.h" #if PG_VERSION_NUM >= 150000 #include "miscadmin.h" #endif /* default value */ char *nls_date_format = NULL; char *orafce_timezone = NULL; extern char *orafce_sys_guid_source; static const struct config_enum_entry orafce_compatibility_options[] = { {"warning_oracle", ORAFCE_COMPATIBILITY_WARNING_ORACLE, false}, {"warning_orafce", ORAFCE_COMPATIBILITY_WARNING_ORAFCE, false}, {"oracle", ORAFCE_COMPATIBILITY_ORACLE, false}, {"orafce", ORAFCE_COMPATIBILITY_ORAFCE, false}, {NULL, 0, false} }; #if PG_VERSION_NUM >= 150000 static shmem_request_hook_type prev_shmem_request_hook = NULL; #endif #if PG_VERSION_NUM >= 150000 static void orafce_shmem_request(void) { if (prev_shmem_request_hook) prev_shmem_request_hook(); RequestAddinShmemSpace(SHMEMMSGSZ); } #endif static bool check_sys_guid_source(char **newval, void **extra, GucSource source) { char *value = *newval; const char *canonicalstr; char *result; if (pg_strcasecmp(value, "uuid_generate_v1") == 0) canonicalstr = "uuid_generate_v1"; else if (pg_strcasecmp(value, "uuid_generate_v1mc") == 0) canonicalstr = "uuid_generate_v1mc"; else if (pg_strcasecmp(value, "uuid_generate_v4") == 0) canonicalstr = "uuid_generate_v1"; else if (pg_strcasecmp(value, "gen_random_uuid") == 0) canonicalstr = "gen_random_uuid"; else return false; #if PG_VERSION_NUM >= 160000 result = (char *) guc_malloc(LOG, 32); if (!result) return false; strcpy(result, canonicalstr); guc_free(*newval); *newval = result; #else result = (char *) malloc(32); if (!result) return false; strcpy(result, canonicalstr); free(*newval); *newval = result; #endif return true; } void _PG_init(void) { #if PG_VERSION_NUM >= 150000 prev_shmem_request_hook = shmem_request_hook; shmem_request_hook = orafce_shmem_request; #else RequestAddinShmemSpace(SHMEMMSGSZ); #endif /* Define custom GUC variables. */ DefineCustomStringVariable("orafce.nls_date_format", "Emulate oracle's date output behaviour.", NULL, &nls_date_format, NULL, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomStringVariable("orafce.timezone", "Specify timezone used for sysdate function.", NULL, &orafce_timezone, "GMT", PGC_USERSET, 0, check_timezone, NULL, NULL); DefineCustomBoolVariable("orafce.varchar2_null_safe_concat", "Specify timezone used for sysdate function.", NULL, &orafce_varchar2_null_safe_concat, false, PGC_USERSET, 0, NULL, NULL, NULL); DefineCustomStringVariable("orafce.sys_guid_source", "Specify function from uuid-ossp extension used for making result.", NULL, &orafce_sys_guid_source, "uuid_generate_v1", PGC_USERSET, 0, check_sys_guid_source, NULL, NULL); DefineCustomEnumVariable("orafce.using_substring_zero_width_in_substr", gettext_noop("behaviour of substr function when substring_length argument is zero"), NULL, &orafce_substring_length_is_zero, ORAFCE_COMPATIBILITY_WARNING_ORACLE, orafce_compatibility_options, PGC_USERSET, 0, NULL, NULL, NULL); EmitWarningsOnPlaceholders("orafce"); RegisterXactCallback(orafce_xact_cb, NULL); }