diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/tsearch/ts_locale.c | 4 | ||||
-rw-r--r-- | src/backend/tsearch/wparser_def.c | 2 | ||||
-rw-r--r-- | src/backend/utils/adt/pg_locale_libc.c | 24 | ||||
-rw-r--r-- | src/include/c.h | 30 | ||||
-rw-r--r-- | src/include/utils/pg_locale.h | 4 | ||||
-rw-r--r-- | src/interfaces/libpq/Makefile | 2 | ||||
-rw-r--r-- | src/pl/plpgsql/src/pl_exec.c | 9 | ||||
-rw-r--r-- | src/test/modules/injection_points/expected/injection_points.out | 16 | ||||
-rw-r--r-- | src/test/modules/injection_points/injection_points--1.0.sql | 12 | ||||
-rw-r--r-- | src/test/modules/injection_points/injection_points.c | 39 | ||||
-rw-r--r-- | src/test/modules/injection_points/sql/injection_points.sql | 7 |
11 files changed, 131 insertions, 18 deletions
diff --git a/src/backend/tsearch/ts_locale.c b/src/backend/tsearch/ts_locale.c index b77d8c23d36..4801fe90089 100644 --- a/src/backend/tsearch/ts_locale.c +++ b/src/backend/tsearch/ts_locale.c @@ -36,7 +36,7 @@ t_isalpha(const char *ptr) { int clen = pg_mblen(ptr); wchar_t character[WC_BUF_LEN]; - pg_locale_t mylocale = 0; /* TODO */ + locale_t mylocale = 0; /* TODO */ if (clen == 1 || database_ctype_is_c) return isalpha(TOUCHAR(ptr)); @@ -51,7 +51,7 @@ t_isalnum(const char *ptr) { int clen = pg_mblen(ptr); wchar_t character[WC_BUF_LEN]; - pg_locale_t mylocale = 0; /* TODO */ + locale_t mylocale = 0; /* TODO */ if (clen == 1 || database_ctype_is_c) return isalnum(TOUCHAR(ptr)); diff --git a/src/backend/tsearch/wparser_def.c b/src/backend/tsearch/wparser_def.c index 79bcd32a063..e2dd3da3aa3 100644 --- a/src/backend/tsearch/wparser_def.c +++ b/src/backend/tsearch/wparser_def.c @@ -299,7 +299,7 @@ TParserInit(char *str, int len) */ if (prs->charmaxlen > 1) { - pg_locale_t mylocale = 0; /* TODO */ + locale_t mylocale = 0; /* TODO */ prs->usewide = true; if (database_ctype_is_c) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index e9f9fc1e369..8d88b53c375 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -457,7 +457,7 @@ strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, /* Output workspace cannot have more codes than input bytes */ workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t)); - char2wchar(workspace, srclen + 1, src, srclen, locale); + char2wchar(workspace, srclen + 1, src, srclen, loc); for (curr_char = 0; workspace[curr_char] != 0; curr_char++) workspace[curr_char] = towlower_l(workspace[curr_char], loc); @@ -468,7 +468,7 @@ strlower_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, max_size = curr_char * pg_database_encoding_max_length(); result = palloc(max_size + 1); - result_size = wchar2char(result, workspace, max_size + 1, locale); + result_size = wchar2char(result, workspace, max_size + 1, loc); if (result_size + 1 > destsize) return result_size; @@ -552,7 +552,7 @@ strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, /* Output workspace cannot have more codes than input bytes */ workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t)); - char2wchar(workspace, srclen + 1, src, srclen, locale); + char2wchar(workspace, srclen + 1, src, srclen, loc); for (curr_char = 0; workspace[curr_char] != 0; curr_char++) { @@ -569,7 +569,7 @@ strtitle_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, max_size = curr_char * pg_database_encoding_max_length(); result = palloc(max_size + 1); - result_size = wchar2char(result, workspace, max_size + 1, locale); + result_size = wchar2char(result, workspace, max_size + 1, loc); if (result_size + 1 > destsize) return result_size; @@ -640,7 +640,7 @@ strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, /* Output workspace cannot have more codes than input bytes */ workspace = (wchar_t *) palloc((srclen + 1) * sizeof(wchar_t)); - char2wchar(workspace, srclen + 1, src, srclen, locale); + char2wchar(workspace, srclen + 1, src, srclen, loc); for (curr_char = 0; workspace[curr_char] != 0; curr_char++) workspace[curr_char] = towupper_l(workspace[curr_char], loc); @@ -651,7 +651,7 @@ strupper_libc_mb(char *dest, size_t destsize, const char *src, ssize_t srclen, max_size = curr_char * pg_database_encoding_max_length(); result = palloc(max_size + 1); - result_size = wchar2char(result, workspace, max_size + 1, locale); + result_size = wchar2char(result, workspace, max_size + 1, loc); if (result_size + 1 > destsize) return result_size; @@ -1130,7 +1130,7 @@ wcstombs_l(char *dest, const wchar_t *src, size_t n, locale_t loc) * zero-terminated. The output will be zero-terminated iff there is room. */ size_t -wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale) +wchar2char(char *to, const wchar_t *from, size_t tolen, locale_t loc) { size_t result; @@ -1160,7 +1160,7 @@ wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale) } else #endif /* WIN32 */ - if (locale == (pg_locale_t) 0) + if (loc == (locale_t) 0) { /* Use wcstombs directly for the default locale */ result = wcstombs(to, from, tolen); @@ -1168,7 +1168,7 @@ wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale) else { /* Use wcstombs_l for nondefault locales */ - result = wcstombs_l(to, from, tolen, locale->info.lt); + result = wcstombs_l(to, from, tolen, loc); } return result; @@ -1185,7 +1185,7 @@ wchar2char(char *to, const wchar_t *from, size_t tolen, pg_locale_t locale) */ size_t char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, - pg_locale_t locale) + locale_t loc) { size_t result; @@ -1220,7 +1220,7 @@ char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, /* mbstowcs requires ending '\0' */ char *str = pnstrdup(from, fromlen); - if (locale == (pg_locale_t) 0) + if (loc == (locale_t) 0) { /* Use mbstowcs directly for the default locale */ result = mbstowcs(to, str, tolen); @@ -1228,7 +1228,7 @@ char2wchar(wchar_t *to, size_t tolen, const char *from, size_t fromlen, else { /* Use mbstowcs_l for nondefault locales */ - result = mbstowcs_l(to, str, tolen, locale->info.lt); + result = mbstowcs_l(to, str, tolen, loc); } pfree(str); diff --git a/src/include/c.h b/src/include/c.h index 04fd23577de..6d4495bdd9f 100644 --- a/src/include/c.h +++ b/src/include/c.h @@ -333,6 +333,36 @@ #endif /* + * pg_assume(expr) states that we assume `expr` to evaluate to true. In assert + * enabled builds pg_assume() is turned into an assertion, in optimized builds + * we try to clue the compiler into the fact that `expr` is true. + * + * This is useful for two purposes: + * + * 1) Avoid compiler warnings by telling the compiler about assumptions the + * code makes. This is particularly useful when building with optimizations + * and w/o assertions. + * + * 2) Help the compiler to generate more efficient code + * + * It is unspecified whether `expr` is evaluated, therefore it better be + * side-effect free. + */ +#if defined(USE_ASSERT_CHECKING) +#define pg_assume(expr) Assert(expr) +#elif defined(HAVE__BUILTIN_UNREACHABLE) +#define pg_assume(expr) \ + do { \ + if (!(expr)) \ + __builtin_unreachable(); \ + } while (0) +#elif defined(_MSC_VER) +#define pg_assume(expr) __assume(expr) +#else +#define pg_assume(expr) ((void) 0) +#endif + +/* * Hints to the compiler about the likelihood of a branch. Both likely() and * unlikely() return the boolean value of the contained expression. * diff --git a/src/include/utils/pg_locale.h b/src/include/utils/pg_locale.h index 1cd7c76a0a7..931f5b3b880 100644 --- a/src/include/utils/pg_locale.h +++ b/src/include/utils/pg_locale.h @@ -214,8 +214,8 @@ extern void report_newlocale_failure(const char *localename); /* These functions convert from/to libc's wchar_t, *not* pg_wchar_t */ extern size_t wchar2char(char *to, const wchar_t *from, size_t tolen, - pg_locale_t locale); + locale_t loc); extern size_t char2wchar(wchar_t *to, size_t tolen, - const char *from, size_t fromlen, pg_locale_t locale); + const char *from, size_t fromlen, locale_t loc); #endif /* _PG_LOCALE_ */ diff --git a/src/interfaces/libpq/Makefile b/src/interfaces/libpq/Makefile index 853aab4b1b8..47d67811509 100644 --- a/src/interfaces/libpq/Makefile +++ b/src/interfaces/libpq/Makefile @@ -87,7 +87,7 @@ endif # that are built correctly for use in a shlib. SHLIB_LINK_INTERNAL = -lpgcommon_shlib -lpgport_shlib ifneq ($(PORTNAME), win32) -SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi_krb5 -lgss -lgssapi -lssl -lsocket -lnsl -lresolv -lintl -lm, $(LIBS)) $(LDAP_LIBS_FE) $(PTHREAD_LIBS) +SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi_krb5 -lgss -lgssapi -lssl -lsocket -lnsl -lresolv -lintl -ldl -lm, $(LIBS)) $(LDAP_LIBS_FE) $(PTHREAD_LIBS) else SHLIB_LINK += $(filter -lcrypt -ldes -lcom_err -lcrypto -lk5crypto -lkrb5 -lgssapi32 -lssl -lsocket -lnsl -lresolv -lintl -lm $(PTHREAD_LIBS), $(LIBS)) $(LDAP_LIBS_FE) endif diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c index b9acc790dc6..d19425b7a71 100644 --- a/src/pl/plpgsql/src/pl_exec.c +++ b/src/pl/plpgsql/src/pl_exec.c @@ -8610,6 +8610,15 @@ exec_set_found(PLpgSQL_execstate *estate, bool state) PLpgSQL_var *var; var = (PLpgSQL_var *) (estate->datums[estate->found_varno]); + + /* + * Use pg_assume() to avoid a spurious warning with some compilers, by + * telling the compiler that the VARATT_IS_EXTERNAL_NON_EXPANDED() branch + * in assign_simple_var() will never be reached when called from here, due + * to "found" being a boolean (i.e. a byvalue type), not a varlena. + */ + pg_assume(var->datatype->typlen != -1); + assign_simple_var(estate, var, BoolGetDatum(state), false, false); } diff --git a/src/test/modules/injection_points/expected/injection_points.out b/src/test/modules/injection_points/expected/injection_points.out index 43bcdd01582..382f3b0bf88 100644 --- a/src/test/modules/injection_points/expected/injection_points.out +++ b/src/test/modules/injection_points/expected/injection_points.out @@ -39,6 +39,15 @@ SELECT injection_points_attach('TestInjectionLog2', 'notice'); (1 row) +SELECT point_name, library, function FROM injection_points_list() + ORDER BY point_name COLLATE "C"; + point_name | library | function +--------------------+------------------+------------------ + TestInjectionError | injection_points | injection_error + TestInjectionLog | injection_points | injection_notice + TestInjectionLog2 | injection_points | injection_notice +(3 rows) + SELECT injection_points_run('TestInjectionBooh'); -- nothing injection_points_run ---------------------- @@ -298,5 +307,12 @@ SELECT injection_points_detach('TestConditionLocal1'); (1 row) +-- No points should be left around. +SELECT point_name, library, function FROM injection_points_list() + ORDER BY point_name COLLATE "C"; + point_name | library | function +------------+---------+---------- +(0 rows) + DROP EXTENSION injection_points; DROP FUNCTION wait_pid; diff --git a/src/test/modules/injection_points/injection_points--1.0.sql b/src/test/modules/injection_points/injection_points--1.0.sql index cc76b1bf99a..5f5657b2043 100644 --- a/src/test/modules/injection_points/injection_points--1.0.sql +++ b/src/test/modules/injection_points/injection_points--1.0.sql @@ -78,6 +78,18 @@ AS 'MODULE_PATHNAME', 'injection_points_detach' LANGUAGE C STRICT PARALLEL UNSAFE; -- +-- injection_points_list() +-- +-- List of all the injection points currently attached. +-- +CREATE FUNCTION injection_points_list(OUT point_name text, + OUT library text, + OUT function text) +RETURNS SETOF record +AS 'MODULE_PATHNAME', 'injection_points_list' +LANGUAGE C STRICT VOLATILE PARALLEL RESTRICTED; + +-- -- injection_points_stats_numcalls() -- -- Reports statistics, if any, related to the given injection point. diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c index 3da0cbc10e0..31138301117 100644 --- a/src/test/modules/injection_points/injection_points.c +++ b/src/test/modules/injection_points/injection_points.c @@ -18,6 +18,7 @@ #include "postgres.h" #include "fmgr.h" +#include "funcapi.h" #include "injection_stats.h" #include "miscadmin.h" #include "nodes/pg_list.h" @@ -545,6 +546,44 @@ injection_points_detach(PG_FUNCTION_ARGS) PG_RETURN_VOID(); } +/* + * SQL function for listing all the injection points attached. + */ +PG_FUNCTION_INFO_V1(injection_points_list); +Datum +injection_points_list(PG_FUNCTION_ARGS) +{ +#define NUM_INJECTION_POINTS_LIST 3 + ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; + List *inj_points; + ListCell *lc; + + /* Build a tuplestore to return our results in */ + InitMaterializedSRF(fcinfo, 0); + + inj_points = InjectionPointList(); + + foreach(lc, inj_points) + { + Datum values[NUM_INJECTION_POINTS_LIST]; + bool nulls[NUM_INJECTION_POINTS_LIST]; + InjectionPointData *inj_point = lfirst(lc); + + memset(values, 0, sizeof(values)); + memset(nulls, 0, sizeof(nulls)); + + values[0] = PointerGetDatum(cstring_to_text(inj_point->name)); + values[1] = PointerGetDatum(cstring_to_text(inj_point->library)); + values[2] = PointerGetDatum(cstring_to_text(inj_point->function)); + + /* shove row into tuplestore */ + tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + } + + return (Datum) 0; +#undef NUM_INJECTION_POINTS_LIST +} + void _PG_init(void) diff --git a/src/test/modules/injection_points/sql/injection_points.sql b/src/test/modules/injection_points/sql/injection_points.sql index d9748331c77..874421e9c11 100644 --- a/src/test/modules/injection_points/sql/injection_points.sql +++ b/src/test/modules/injection_points/sql/injection_points.sql @@ -18,6 +18,9 @@ SELECT injection_points_attach('TestInjectionError', 'error'); SELECT injection_points_attach('TestInjectionLog', 'notice'); SELECT injection_points_attach('TestInjectionLog2', 'notice'); +SELECT point_name, library, function FROM injection_points_list() + ORDER BY point_name COLLATE "C"; + SELECT injection_points_run('TestInjectionBooh'); -- nothing SELECT injection_points_run('TestInjectionLog2'); -- notice SELECT injection_points_run('TestInjectionLog2', NULL); -- notice @@ -85,5 +88,9 @@ SELECT injection_points_detach('TestConditionError'); SELECT injection_points_attach('TestConditionLocal1', 'error'); SELECT injection_points_detach('TestConditionLocal1'); +-- No points should be left around. +SELECT point_name, library, function FROM injection_points_list() + ORDER BY point_name COLLATE "C"; + DROP EXTENSION injection_points; DROP FUNCTION wait_pid; |